Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors from decoder/encoder not handled properly #1551

Closed
evilworm opened this issue Aug 31, 2022 · 6 comments
Closed

Errors from decoder/encoder not handled properly #1551

evilworm opened this issue Aug 31, 2022 · 6 comments
Labels
bug Something isn't working
Milestone

Comments

@evilworm
Copy link

Describe the bug
Socket.io-client does not handle errors thrown by default parser "socket.io-parser". When parser throws an error, there is no event fired (disconnected, connect_error, etc). The worst case scenario is if you have a binary data being transfered and the decoder has "this.reconstructor" set to true, but receives a string for some reason... the connection goes into limbo state and never recovers.

This does not happen when using for example msgpack parser since it does not throw any errors at all.
Also this does not seem to be an issue with socker.io-parser since its completely legit that the parser throws an error.

To Reproduce
You can manually throw an error in manager.js where "this.decoder.add(data);" line is and watch that you don't get any error emitted, but the console still shows the error.

Socket.IO client version: 4.5.1

Expected behavior
Disconnect the socket on decoder error, emit an error and auto-reconnect.
Also this seems to be fixed in socket.io server code - the decoder.add part is wrapped with try/catch block

Platform:

  • Device: iPhone 13 Pro Max
  • OS: ios 15.6.1 running on Angular PWA (safari engine)

Additional context
Actual real life scenario when this happens: Angular PWA app running on iPhone ... socketio connection receives mpeg-ts binary data. The binary data is split into two packets, the decoder tries to reconstruct it. When you swipe away from the application, system will put app to sleep in about a few seconds without disconnecting the socket. When the application wakes up, the connection is lost and socket is reconnected, however the decoder still might expect binary data (having this.reconstructor flag set to true) and throws an error "got plaintext data when reconstructing a packet" which is not handled by socket.io properly and the connection stalls.
Unfortunately forceNew flag has no effect in pwa app since the object is not re-created when app wakes up.

@evilworm evilworm added the to triage Waiting to be triaged by a member of the team label Aug 31, 2022
darrachequesne added a commit that referenced this issue Sep 2, 2022
The decoder can throw an error when trying to decode an invalid payload
sent by the server, so the manager will now catch it, close the
connection and then reconnect instead of crashing.

Related:

- socketio/socket.io#4392
- #1551
@darrachequesne
Copy link
Member

Thanks a lot for the detailed issue 👍

This should be fixed by c597023, included in version 4.5.2.

@darrachequesne darrachequesne added bug Something isn't working and removed to triage Waiting to be triaged by a member of the team labels Sep 2, 2022
@darrachequesne darrachequesne added this to the 4.5.2 milestone Sep 2, 2022
@tybruffy
Copy link

Looks like this may have had some unintended side effects?

Recently upgraded from 4.5.1 and suddenly stopped seeing errors in my browser console. This is causing errors to fail silently with no way to track them down?

I had a check against a var.length in the ack callback from an emit on the client side, where var was unintentionally null. Instead of seeing the error " Cannot read properties of null (reading 'length')" in my console like I would have before upgrading, the error is silenced and the socket disconnects and reconnects.

Seems like we should still have the ability to see the output of the error instead of just silently passing "parse error" to the close function, no?

@darrachequesne
Copy link
Member

@tybruffy hmm, it seems you are right. On the server-side, the onpacket method is wrapped with process.nextTick(), so any error thrown in a listener is not caught by the try ... catch:

process.nextTick(function () {
  socket._onpacket(packet);
});

Source: https://github.com/socketio/socket.io/blob/10fa4a2690fafcf9415e49aad507394e0b9a9ab0/lib/client.ts#L288-L290

@mhio
Copy link

mhio commented Sep 20, 2022

The error handler added in c597023 is masking regular errors in socket.on('x') functions for me too.

Why is the caught error e being discarded? The close/disconnect sounds a valid mechanism but can the e be emitted as an error? or least be attached to the close reason?

Although in the broader sense, the change introduced to the default error handling behaviour might not be just a point release.

darrachequesne added a commit to socketio/engine.io-client that referenced this issue Oct 13, 2022
darrachequesne added a commit that referenced this issue Oct 13, 2022
Following [1], any exception in a user-provided event listener would
get caught in the try...catch of the decoder and result in the
reconnection of the socket.

[1]: c597023

Related:

- #1551
- #1554
- #1557
@darrachequesne
Copy link
Member

This should be fixed by 2403b88, included in version 4.5.3.

@darrachequesne darrachequesne modified the milestones: 4.5.2, 4.5.3 Oct 15, 2022
@aovchinn
Copy link

aovchinn commented Apr 5, 2024

 The binary data is split into two packets, the decoder tries to reconstruct it.
 When you swipe away from the application, system will put app to sleep in about a few seconds without 
 disconnecting the socket. When the application wakes up, the connection is lost and socket is reconnected, 
 however the decoder still might expect binary data (having this.reconstructor flag set to true)

should it just clear this.reconstructor on reconnection/connection loss ?

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants