#Global APP_GUARD, APP_PIPE and so on do not apply to WS gateways

26 messages · Page 1 of 1 (latest)

worn fern
#

I'm assuming this behaviour is by design, but I'm looking to learn of any practical alternatives.

In short, I already have a few global providers that were supposed to be app-wide such as for example:

{
  provide: APP_PIPE,
  useValue: new ValidationPipe({
    transform: true,
    forbidUnknownValues: true,
    forbidNonWhitelisted: true,
    whitelist: true,
  }),
},

Unfortunately come to find out those do not trigger on WS gateways. (Unless I'm doing something wrong of course).

If so, what's the best practice in that scenario?

Thanks.

devout timber
#

Yes, they don't. The same happens in hybrid apps where global enhancers bound this way don't apply to microservice controllers, only HTTP controllers. (although there's an option to inherit them in this case)

#

Sadly, for WS, there's no such option, so you have to bind them explicitly to the gateway with @UsePipes()

worn fern
#

Oh noes..

#

I guess a nice middle ground would be to have a base class WsGateway that has all of them applied for example..

devout timber
#

if you want to re-use the same instance, create the pipe in some shared file

export const validationPipe = new ValidationPipe({ ... })

And then bind it with @UsePipes(validationPipe) and { provide: APP_PIPE, useValue: validationPipe }

devout timber
worn fern
devout timber
worn fern
#
  • Maybe with an automatic exception filter for converting the HttpExceptions usually thrown by global app guards, interceptors, etc, to WsExceptions.
devout timber
#

There's one issue that if you use global enhancers, as soon as you added WS, then all of those would need to be compatible with WS as well which is not usually the case. Consider auth guards for example. All in all it's not as simple as it seems, and to be honest, you don't usually have hundreds of WS gateways for a little bit of repetition to become a major issue.

worn fern
#

You have a point. However, I would assume many global enhancers are also pretty generic in that, they don't particularly rely on the app's business logic to function (such as auth guards for example). I'm guessing in many cases we'll see things such as my global validation pipe in the initial message and things of that nature.

I'd love to discuss this with others to see what they think. (guidance would be appreciated as to where I would do that exactly, maybe raise an issue as a feature request would be best?).

Nevertheless, I'll be keeping an eye on that front if there's any advancements on the matter.

[Ref](#1205457272675762247 message): Also, the base class validation pattern seems to work upon doing some quick tests.

worn fern
#

In addition to this discussion, I would like point out that the official docs mention the use of "regular" built-in pipes which don't play nicely with ws gateways by default.

Something like this 'fixes' the issues that otherwise occur.

@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 {}
devout timber
#

But the issue you're describing is inherent to a wrong use of HttpException, not an issue with Nest itself. It is a transport-specific exception that should be only thrown from pieces of code that use that transport (HTTP), not from transport-agnostic services in your application code. Instead, you should define application-specific errors and then translate them to transport-specific errors in the transport layer.

worn fern
#

Unless I'm missing the point..

devout timber
worn fern
#

At least on my machine confusedCat

devout timber
worn fern
#

So would that be considered a bug..?

#

Or just a human error in the docs (meaning you're not supposed to use ValidationPipe and such on ws gateways)?

devout timber
#

Honestly I don't know. Might be worth creating an official issue (after searching a similar one does not exist) and explaining the situation

#

(in a way that Kamil doesn't think it's just a question and closes it while directing you to discord, where we can't really do much other than rant about it)

worn fern
#

Okay. PepeOk