leapmotion/leapjs

Unexpected end of JSON input

aknoerig opened this issue · 3 comments

When using leapjs via node, the frame data once in a while seems to be incomplete and crashes with the error below.

So far I couldn't find a way for error handling this properly, so this is also crashing my node server, stopping all processes.

Is there maybe a callback for this error, or a way to wrap this in a try/catch block?

SyntaxError: Unexpected end of JSON input
    at Object.parse (native)
    at BaseConnection.handleData (.../node_modules/leapjs/lib/connection/base.js:135:22)
    at WebSocket.<anonymous> (.../node_modules/leapjs/lib/connection/node.js:19:49)
    at emitTwo (events.js:106:13)
    at WebSocket.emit (events.js:191:7)
    at Receiver.self._receiver.ontext (.../node_modules/leapjs/node_modules/ws/lib/WebSocket.js:544:10)
    at Receiver.finish (.../node_modules/leapjs/node_modules/ws/lib/Receiver.js:397:14)
    at Receiver.expectHandler (.../node_modules/leapjs/node_modules/ws/lib/Receiver.js:384:31)
    at Receiver.add (.../node_modules/leapjs/node_modules/ws/lib/Receiver.js:93:24)
    at Socket.firstHandler (.../node_modules/leapjs/node_modules/ws/lib/WebSocket.js:524:22)

What version of LeapJS are you using? What version of the leap Service? What hardware?

As a hack, you should be able to put a try/catch inside the handleData method, or even replace the whole method with a wrapped version. Of course that's no real solution to the underlying issue.

pseudocode:

handleData = myController.connection.handleData
myController.connection.handleData = function() {
   try {
    handleData()
   }
}

Thanks for the suggestion! I'm using LeapJS 0.6.4, service 2.3.1 on macOS Sierra, model LM-010.

Indeed the hack seems to work when fleshed out like this:

myController.on('connect', function() {
  var origHandleData = this.connection.handleData;
  this.connection.handleData = function(data) {
    try {
      return origHandleData.call(this, data);
    } catch (e) {
      console.log(e);
    }
  };
});

Anyway, I believe this needs to be fixed in the library, maybe in the form of an error callback:

myController.on('error', function() {...});

Otherwise leapjs cannot be used safely with node at this point.

I encountered the same problem. I solved this directly inside the leapjs code by surrounding the JSON.parse(data) with a try-catch-block.

BaseConnection.prototype.handleData = function(data) {
    try {
        var message = JSON.parse(data);
        var messageEvent;
        if (this.protocol === undefined) {
          messageEvent = this.protocol = chooseProtocol(message);
          this.protocolVersionVerified = true;
          this.emit('ready');
        } else {
          messageEvent = this.protocol(message);
        }
        this.emit(messageEvent.type, messageEvent);
    } catch(err) {
        // do nothing if data is invalid
    }
}

Anyway I believe too that this should be fixed inside the library itself as aknoerig suggested.