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

grpc-json: Handle streaming backend error cases correctly #8315

Closed
nareddyt opened this issue Sep 21, 2019 · 2 comments · Fixed by #8323
Closed

grpc-json: Handle streaming backend error cases correctly #8315

nareddyt opened this issue Sep 21, 2019 · 2 comments · Fixed by #8323
Labels
enhancement Feature requests. Not bugs or questions.
Milestone

Comments

@nareddyt
Copy link
Contributor

The grpc-json-transcoder filter does not handle errors from streaming backends correctly. I opened this issue to document the current and proposed downstream responses.

Note that #8009 introduced a new convert_grpc_status flag to deduce the HTTP response code and body from the gRPC backend error. This flag introduces another edge case (below).

I think the logic for unary responses is OK. I've only seen these issues with streaming backends.

cc @qiwzhang
cc @ascheglov

Streaming Error with flag set

Configuration: The backend returns a gRPC error via a trailer-only response. The filter is configured with convert_grpc_status=true.

Current Behavior

The filter returns a HTTP 200 OK. The grpc status flag is set in one of the response headers. Assuming that #8312 will be merged in, the response will be [] with content-type application/json.

Proposed Behavior

The filter should return a response that matches the unary case with convert_grpc_status set:

  • The HTTP code should match the gRPC status code.
  • The response body should be a JSON with the error message.

Streaming Error without flag

Configuration: The backend returns a gRPC error via a trailer-only response. The filter is configured without convert_grpc_status (default behavior).

Current Behavior

Same as above: The filter returns a HTTP 200 OK. The grpc status flag is set in one of the response headers. Assuming that #8312 will be merged in, the response will be [] with content-type application/json.

Proposed Behavior

The filter should return a response that exposes the error:

  • The HTTP code should match the gRPC status code.
  • The body should be completely empty (""), not an empty JSON array
  • Content type should not be set, or it shouldn't matter what it is set to

Other Notes

I would prefer to get #8312 merged in first to fix the content type issue. Please advise on how to handle this, as it may be a breaking change (?)

@nareddyt
Copy link
Contributor Author

FYI the behavior of the first case (streaming error with flag set) is a bug. The convert_grpc_status flag does not do anything.

This can be verified by adding the following test case to //test/extensions/filters/http/grpc_json_transcoder/grpc_json_transcoder_integration_test.cc, under the UnaryErrorConvertedToJson test. It will fail.

// 2: Empty response (trailers only) from streaming backend, with a gRPC error.
  testTranscoding<bookstore::ListBooksRequest, bookstore::Book>(
      Http::TestHeaderMapImpl{
          {":method", "GET"}, {":path", "/shelves/37/books"}, {":authority", "host"}},
      "", {"shelf: 37"}, {}, Status(Code::NOT_FOUND, "Shelf 37 Not Found"),
      Http::TestHeaderMapImpl{{":status", "404"},
                              {"content-type", "application/json"},
                              {"grpc-status", UnexpectedHeaderValue},
                              {"grpc-message", UnexpectedHeaderValue}},
      "[]");

@ascheglov
Copy link
Contributor

Here is what happens in case of a trailer-only streaming error:
The transcoder filter gets encodeHeaders with end_stream=true, then it
asks the transcoder if it has any data to encode, and transcoder returns that [].
Then since there is some response data, the filter sets its has_body_ flag and doesn't transcode the gRPC error headers.

Well, we can fix that. There is no need to ask the transcoder for data if we know that it's a trailers-only response.

ascheglov pushed a commit to ascheglov/envoy that referenced this issue Sep 22, 2019
When a streaming backend returns an error in a trailer-only response,
with the 'convert_grpc_status' option enabled,
instead of writing the [] (empty array) in reply-body
transcode the error in the headers and reply with {"code":...}.

Risk Level: Low
Testing: added an integraion test, tested manually.
Documentation: n/a
Release notes: n/a
Fixes envoyproxy#8315

Signed-off-by: Anatoly Scheglov <[email protected]>
@mattklein123 mattklein123 added the enhancement Feature requests. Not bugs or questions. label Sep 27, 2019
@mattklein123 mattklein123 added this to the 1.12.0 milestone Sep 27, 2019
lizan pushed a commit that referenced this issue Oct 3, 2019
When a streaming backend returns an error in a trailer-only response,
with the 'convert_grpc_status' option enabled,
instead of writing the [] (empty array) in reply-body
transcode the error in the headers and reply with {"code":...}.

Risk Level: Low
Testing: added an integraion test, tested manually.
Documentation: n/a
Release notes: n/a
Fixes #8315

Signed-off-by: Anatoly Scheglov <[email protected]>
danzh2010 pushed a commit to danzh2010/envoy that referenced this issue Oct 4, 2019
…#8323)

When a streaming backend returns an error in a trailer-only response,
with the 'convert_grpc_status' option enabled,
instead of writing the [] (empty array) in reply-body
transcode the error in the headers and reply with {"code":...}.

Risk Level: Low
Testing: added an integraion test, tested manually.
Documentation: n/a
Release notes: n/a
Fixes envoyproxy#8315

Signed-off-by: Anatoly Scheglov <[email protected]>
nandu-vinodan pushed a commit to nandu-vinodan/envoy that referenced this issue Oct 17, 2019
…#8323)

When a streaming backend returns an error in a trailer-only response,
with the 'convert_grpc_status' option enabled,
instead of writing the [] (empty array) in reply-body
transcode the error in the headers and reply with {"code":...}.

Risk Level: Low
Testing: added an integraion test, tested manually.
Documentation: n/a
Release notes: n/a
Fixes envoyproxy#8315

Signed-off-by: Anatoly Scheglov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature requests. Not bugs or questions.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants