nest icon indicating copy to clipboard operation
nest copied to clipboard

`ValidationPipe` and possibly others throw `HttpException` when used on WS gateways

Open StiliyanKushev opened this issue 1 year ago • 1 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Current behavior

In the following example if the ValidationPipe was to ever throw, it would cause an internal error rather then WsException.

@UsePipes(
  new ValidationPipe({
    transform: true,
    forbidUnknownValues: true,
    forbidNonWhitelisted: true,
    whitelist: true,
  }),
)
@WebSocketGateway({ namespace: 'something' })
export class SomethingGateway {}

To workaround this at the moment one possible solution is to patch it with an exception filter like so:

@Catch()
export class WsExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    if (exception instanceof HttpException) {
      super.catch(new WsException(exception.getResponse()), host);
    } else {
      super.catch(exception, host);
    }
  }
}

@UseFilters(WsExceptionsFilter)
@UsePipes(
  new ValidationPipe({
    transform: true,
    forbidUnknownValues: true,
    forbidNonWhitelisted: true,
    whitelist: true,
  }),
)
@WebSocketGateway({ namespace: 'something' })
export class SomethingGateway {}

That's because by the looks of it ValidationPipe always throws an HttpException regardless of the protocol of the current execution context.

Minimum reproduction code

https://github.com/StiliyanKushev/ws-exception-validation-pipe-reproduction-repo

Steps to reproduce

npm ci
npm run test:e2e

Expected behavior

I expected ValidationPipe to throw a WsException when used inside of a WS gateway.

Package

  • [ ] I don't know. Or some 3rd-party package
  • [X] @nestjs/common
  • [ ] @nestjs/core
  • [ ] @nestjs/microservices
  • [ ] @nestjs/platform-express
  • [ ] @nestjs/platform-fastify
  • [ ] @nestjs/platform-socket.io
  • [ ] @nestjs/platform-ws
  • [ ] @nestjs/testing
  • [ ] @nestjs/websockets
  • [ ] Other (see below)

Other package

No response

NestJS version

10.3.0

Packages versions

[System Information]
OS Version     : Linux 6.6.8-zen1-1-zen
NodeJS Version : v20.8.0
NPM Version    : 10.1.0 

[Nest CLI]
Nest CLI Version : 10.3.2 

[Nest Platform Information]
platform-socket.io version : 10.3.2
platform-express version   : 10.3.2
websockets version         : 10.3.2
schematics version         : 10.1.1
testing version            : 10.3.2
common version             : 10.3.2
core version               : 10.3.2
cli version                : 10.3.2

Node.js version

No response

In which operating systems have you tested?

  • [ ] macOS
  • [ ] Windows
  • [X] Linux

Other

Alternatively, if we're meant not to be using ValidationPipe on WS gateways, then the docs should be updated.

As of now, the docs clearly showcase the possible use of ValidationPipe inside WS gateways as seen here: image

StiliyanKushev avatar Feb 09 '24 14:02 StiliyanKushev

The ValidationPipe constructor can also receive an exceptionFactory to create your exceptions. Then, you could have the options for the WebSocketGateway validators as a shared constant. I have been doing this for errors thrown in the RPC ExecutionContext type.

getlarge avatar Mar 26 '24 09:03 getlarge