Skip to content

Conversation

@manureja64
Copy link
Contributor

BaseWsExceptionFilter used client.emit() to send exception payloads, which only works with socket.io. For native WebSocket clients (ws library), emit() is just EventEmitter.emit() and does not send data over the wire, causing exceptions to be silently swallowed.

Add sendExceptionToClient() and isNativeWebSocket() methods to BaseWsExceptionFilter to detect the client type and use client.send() for native WebSocket clients. Update WsExceptionsHandler guard to allow clients with send() through to the exception filter.

Closes #9056

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

When a WsException is thrown inside a gateway handler that uses @nestjs/platform-ws (raw ws library), the exception is silently swallowed — the client never receives any error. This happens because BaseWsExceptionFilter calls client.emit('exception', payload), which is a socket.io-specific method. On raw ws WebSocket clients, .emit() is inherited from Node's EventEmitter and only dispatches events locally — it does not send anything over the wire. Additionally, the guard in WsExceptionsHandler (!client.emit) always passes for ws clients since they inherit .emit from EventEmitter, but the subsequent client.emit() call in the filter does nothing useful.

Issue Number: #9056

What is the new behavior?

  • BaseWsExceptionFilter now has a sendExceptionToClient() method that detects the client type and uses the appropriate transport:
  • Native ws clients (detected via send + numeric readyState + no nsp): sends JSON.stringify({ event, data: payload }) via client.send(), matching the format used by WsAdapter.bindMessageHandlers for normal
    responses
  • Socket.io clients: uses client.emit(event, payload) (existing behavior, unchanged)
  • isNativeWebSocket() helper method distinguishes raw ws clients from socket.io sockets
  • WsExceptionsHandler guard updated from !client.emit to !client.emit && !client.send so raw ws clients reach the exception filter
  • Both sendExceptionToClient() and isNativeWebSocket() are protected, allowing users who extend BaseWsExceptionFilter to override them for custom adapters

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Unit tests added for raw ws client error delivery, readyState guard, bare client bail-out, and isNativeWebSocket detection. E2e test added to verify WsException errors are received by raw ws clients when using WsAdapter.

BaseWsExceptionFilter used client.emit() to send exception payloads,
which only works with socket.io. For native WebSocket clients (ws
library), emit() is just EventEmitter.emit() and does not send data
over the wire, causing exceptions to be silently swallowed.

Add sendExceptionToClient() and isNativeWebSocket() methods to
BaseWsExceptionFilter to detect the client type and use client.send()
for native WebSocket clients. Update WsExceptionsHandler guard to
allow clients with send() through to the exception filter.

Closes nestjs#9056
@coveralls
Copy link

Pull Request Test Coverage Report for Build 4be5b7a3-a46b-47a1-ac30-fea040e374e6

Details

  • 10 of 10 (100.0%) changed or added relevant lines in 2 files are covered.
  • 64 unchanged lines in 7 files lost coverage.
  • Overall coverage decreased (-0.06%) to 89.766%

Files with Coverage Reduction New Missed Lines %
packages/microservices/errors/max-packet-length-exceeded.exception.ts 1 50.0%
packages/microservices/helpers/json-socket.ts 3 93.18%
packages/common/pipes/file/file-type.validator.ts 4 90.24%
packages/common/pipes/validation.pipe.ts 10 90.68%
packages/microservices/client/client-tcp.ts 12 85.06%
packages/microservices/server/server-mqtt.ts 16 83.04%
packages/microservices/server/server-tcp.ts 18 75.0%
Totals Coverage Status
Change from base Build a37b4272-bd8e-4a29-b752-179f6dce50e3: -0.06%
Covered Lines: 7447
Relevant Lines: 8296

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Not throwing the exception/error when using ws adapter websocket

4 participants