Skip to content
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

Return 400 Bad Request to REST downstreams if the request is invalid #135

Open
hperl opened this issue Sep 20, 2024 · 1 comment
Open

Return 400 Bad Request to REST downstreams if the request is invalid #135

hperl opened this issue Sep 20, 2024 · 1 comment

Comments

@hperl
Copy link

hperl commented Sep 20, 2024

When transcoding REST to a gRPC upstream, by default, all bad requests return a 500 instead a 400. The final error and status code can be rewritten in an HTTP middleware, but the error messages do not share a common prefix, so that I need to pattern-match all possible errors. For example:

  • passing a body to an endpoint that does not expect a body (no body set in the google.api.http option) returns: request should have no body; instead got %d bytes

  • passing invalid JSON to an endpoint that expects a body returns either proto: unexpected EOF or grpc: error unmarshalling request: proto: unexpected EOF , depending on the HTTP method (I think)

There might be other cases that I missed. Ideally, these error messages would all share a common prefix (i.e. vanguard: invalid request) so that some middleware can catch them and return a 400 ; or Vanguard would return a 400 to downstream for all decoding errors of the request by default.

@jhump
Copy link
Member

jhump commented Sep 20, 2024

For the first one (request should have no body), that indeed can and should be fixed. The second one is less clear thanks to the gRPC docs/specs for error-handling.

If vanguard did not have to transcode the request (i.e. the request was in JSON, but the server also supported JSON), then no translation would happen and it would be the downstream handler/server that parses the request and fails. In this scenario, the downstream handler would return an "internal" error which vanguard then translates to a 500 status code. Here are the relevant parts of the docs/specs:

  • When the request cannot be parsed, it returns an "internal" gRPC error code (link to spec)
  • The "internal" gRPC error code get translated to "500 Internal Server Error" (link to spec).

Unfortunately, the specs don't allow the RPC library to generate an "invalid argument" error when trying to parse a request, which is the gRPC code that would map to a "400 Bad Request" (link to spec).

So vanguard currently treats this situation as a "500" for consistency -- the client should ideally observe the same behavior as if vanguard weren't necessary/in use.

We could possibly make an exception specifically for mapping RPC errors for REST clients. Since REST error semantics differ from gRPC and ConnectRPC semantics, we might accommodate this in Vanguard's transcoding and special-case some errors to return the more conventional REST error code (like "400" in this particular case).

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

No branches or pull requests

2 participants