-
-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
fix(core): Change BaseExceptionFilter to only handle REST calls #5972
Conversation
applicationRef.reply(ctx.getResponse(), message, statusCode); | ||
} else { | ||
// Let the RPC / GraphQL framework handle building the response. | ||
throw exception; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if there is no error handler? Say for TCP, if you just throw and error, how does the server handle it? What's the response to the client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically this was the behavior so far. Because the original code called applicationRef.reply
with host.getArgByIndex(1)
which resolves to a context object on RPC, a client object on WS, and args on GQL. Then, for example the express implementation of .reply
would simply invoke .send
which will throw an exception for everything except for REST (IIUC).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmcdo29 TCP (and any other microservices) uses BaseRpcExceptionFilter
instead so this class won't be (and shouldn't be used) by any other transport strategy (including GQL btw)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nirga what's the reason for making BaseRpcExceptionFilter
context-aware and adding an additional if
condition that will run for every error thrown from the HTTP app (which has a very little impact on the performance, but still), when:
- WS apps should use
BaseWsExceptionFilter
instead (https://docs.nestjs.com/websockets/exception-filters#inheritance - Microservices (including gRPC) should use
BaseRpcExceptionFilter
as mentioned here https://docs.nestjs.com/microservices/exception-filters#inheritance
and GraphQL shouldn't inherit from ANY class as it doesn't bring any benefit (there's no logic in the GQL exception filter, it simply re-throws an error down to the Apollo server - as I've mentioned here #5958 (comment))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kamilmysliwiec! I actually didn't realize there are multiple different base filters for each protocol.
The reason for me to write this was basically to support a use case we're having now - where we have an app that communicates in both GraphQL and REST, and we don't want to interfere with the normal exception treatment of Nest, just add some logging of the fact that an error occurred. So extending BaseExceptionFilter
seemed to be the right thing to do, and I guess that given the multi protocols we have in the server (and I'm not sure if it's a common use case or a really strange thing to do), we actually won't be able to use any Exception Filter.
I'd guess that then maybe it's better to rename this filter to BaseHttpExceptionFilter or something like that so it'll be clearer? And what about creating some "catch all" base exception filter that support the default behavior for all types of protocols (not necessarily just one)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd guess that then maybe it's better to rename this filter to BaseHttpExceptionFilter or something like that so it'll be clearer?
I'd prefer using a BaseHttpExceptionFilter
name instead as well, but now it's too late to introduce a breaking change (and force people to update their code) just to change a class name, unfortunately.
And what about creating some "catch all" base exception filter that support the default behavior for all types of protocols (not necessarily just one)?
This would require providing a separate package. Adding this to the core
would create circular dependencies with @nestjs/websockets
and @nestjs/microservices
.
Regarding #5958 I have both REST and GraphQL APIs. Here is a solution that worked for me:
|
I've just read the whole conversation above. And I don't understand — why exactly did this PR not get merged? It forces us still to write this boilerplate (in apps that use both REST and GraphQL). Why won't the framework do it for us? |
Fixes #5958
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
What is the new behavior?
Does this PR introduce a breaking change?
Other information