Skip to content

[BUG] err: Error: Invalid access of closed uWS.WebSocket/SSLWebSocket. #1273

@oprypkhantc

Description

@oprypkhantc

Description

Hey. We're using Soketi in a setup where automated Playwright tests start browser instances, which in turn load the page and connect to Soketi through JavaScript Pusher SDK. Generally this works correctly, but sometimes we get this error:

  process uncaughtException  
{
  err: Error: Invalid access of closed uWS.WebSocket/SSLWebSocket.
      at /app/dist/ws-handler.js:63:27
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (node:internal/process/task_queues:96:5),
  origin: 'unhandledRejection'
}
  🚫 New users cannot connect to this instance anymore. Preparing for signaling...  
  ⚡ The server is closing and signaling the existing connections to terminate.  

Which seems to be caused by a closed connection that wasn't handled gracefully somewhere. It's hard to tell exactly when or why this happens, and in of itself, the dropped connection isn't a problem. However, this unhandled promise rejection causes the server to restart, which in turn causes 502 Gateway timeouts from our backend trying to reach Soketi's API.

Reproduction steps
Hard to tell. Does not happen locally, and only happens under load on a production-like environment.

Expected behavior
No error and hence, no server restart.

Environment

  • Soketi version (i.e. 1.3.0): 1.6.0, but doesn't look relevant to 1.6.1 fixes
  • Adapter (local, redis): redis
  • App Manager (array, mysql, postgres, dynamodb) : dynamodb
  • Queue (sqs, redis, sync): sync
  • Cache Managers (memory, redis): memory

Additional context

Line from the error maps to this line in the sources: https://github.com/soketi/soketi/blob/1.x/src/ws-handler.ts#L104
Which suggests something like this:

  1. onOpen() is called
  2. checkForValidApp() promise goes to cache/dynamoDB to check for the application
  3. connection is closed (for any reason)
  4. onClose() is called
  5. checkForValidApp() promise resolves, but the connection is already closed

Could something like this be happening? If so, it's probably best to add an internal state that is set synchronously to CLOSED on onClose(), and check that state before sending anything to the client. That's a lot of boilerplate though, so maybe there's any other solution you can suggest?

I can implement the fix myself, just need direction from someone with more knowledge of how Soketi functions internally. Thanks.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions