rethinkdb-websocket-server: Error: Uncaught SyntaxError: Unexpected token in JSON

We’ve been experiencing a weird bug off and on over the past few months, and lately it seems to be getting worse.

  • Symptom: a syntax error in JSON parsing on the client. It’s like part of the JSON message gets dropped or mangled in transmission. For example:
Error: Uncaught SyntaxError: Unexpected token , in JSON at position 289587
  • Clients: Chrome on OS X and Windows. It seems to occur much more frequently on OS X, and possibly not at all on Windows (we haven’t been able to repro on Windows)
  • Versions: rethinkdb-websocket-server v0.5.1, react-rethinkdb v0.5.1
  • It seems to occur much more frequently (possibly exclusively) when the returned object is big / complicated.
  • Sometimes it happens 50% of the time for big objects, sometimes 0%, sometimes 100% of the time
  • We’re using wss://

I’m going to keep looking into this but I don’t have many ideas about where to start. Does anything jump out?

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Comments: 15 (3 by maintainers)

Most upvoted comments

Hi all.

I’ve been experiencing this bug too, as described towards the end in #24.

I’ve done a little digging and have been able to locate the bug and fix it too 😃

The bug is in the rethinkdb-websocket-client library. Deep down in the socket handling code a FileReader object is used to read binary blobs off the websocket. Thing is, the FileReader load-events are not guaranteed to be delivered sequentially, at least not in Chrome where I have been troubled. It seems smaller blobs load faster than larger blobs (see below).

So a websocket read batch that looks like this in the browser network console:

65424 65424 65424 65424 31354

would sometimes be delivered as follows by the Socket object:

65424 65424 65424 31354 65424

ouch! that breaks the JSON parsing for sure 😃

I’ve made a patch for the Socket object defined in /dist/index.js (lineno 6000-ish ) to ensure sequential delivery, and verified that it sucessfully corrects out-of-order batches from the FileReader.

// Socket constructor variables
var count = 0;
var pending = {};
var stack = [];

// in ws.onmessage
if (typeof Blob !== 'undefined' && data instanceof Blob) {
   count += 1;
   var id = count;
   stack.push(id);
   (0, _blobToBuffer2['default'])(data, function (err, buffer) {
	if (err) {throw err;}
        pending[id] = buffer;
	// ensure events are emitted sequentially 
        var _id = stack[0];	  
        while (pending.hasOwnProperty(_id)) {
		  var buf = pending[_id];
		  emitter.emit('data', buf);
		  delete pending[_id];
		  stack.shift();
		  if (stack.length === 0) {
		    	// no more elements
		    	break;
		  } else {
		      _id = stack[0];
		  }
        } 
    });
}

Cheers, Ingar

@ingararntzen oh my gosh! This really helps. Awesome!

@coffenbacher thank you too. Didn’t notice this comment. The fix is not a lie.

UPD. actually, it is still possible to get the same error. However, looks like this appear less frequently