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

Error sent from streaming method not being returned #287

Closed
jonahbron opened this issue Apr 19, 2018 · 8 comments
Closed

Error sent from streaming method not being returned #287

jonahbron opened this issue Apr 19, 2018 · 8 comments

Comments

@jonahbron
Copy link

jonahbron commented Apr 19, 2018

My method handler code looks something like this:

try {
  upload(call.request).subscribe(
    (result: UploadResult) => call.write(result),
    (error) => call.destroy(error),
    () => call.end()
  );
  call.end();
} catch (error) {
  call.destroy(error);
}

The upload() method throws an object that looks like this:

{ code: grpc.status.UNAUTHENTICATED, message: 'No session token provided' }

But that error is never making it back to the client. The response is completely empty. Is this the wrong way to pass an error to the client from a streaming API? Perhaps an important detail is that I'm using the Improbable GRPC-Web proxy, I suppose it's possible that the error isn't making it through the proxy. I want to make sure I'm doing this part correctly though, as none of the docs I've seen mention how to throw errors from a server-streaming API.

@murgatroid99
Copy link
Member

I don't recognize that API. Is that code using the Node gRPC library? How is grpc-web involved?

Whatever the answer is, that error is almost definitely being output by some kind of asynchronous operation. A try...catch block won't handle that, so you probably need some kind of callback or error handler method; whatever is appropriate for that API.

@jonahbron
Copy link
Author

Sorry I wasn't clear, that code is inside of a method handler. Don't worry about the grpc-web detail, that's just the client.

The call variable there is an argument received by the handler, it's a ServerWritableStream.

https://grpc.io/grpc/node/grpc-ServerWritableStream.html

And in my debugging, I can see that the error is definitely being sent to the destroy() method directly.

Here's a simplified handler function that I just tested in my app to ensure the error isn't making it to the client.

function uploadHandler(call) {
  call.destroy({ code: status.UNKNOWN, message: 'Error' });
}

(that gets passed to server.addService)

Alternatively for example, a unary API error response works fine:

function uploadHandler(call, callback) {
  callback({ code: status.UNKNOWN, message: 'Error' }, null);
}

@murgatroid99
Copy link
Member

OK, that's interesting. I didn't know about the destroy stream method, and we've never tested it. So, I don't know what it does here. I would have expected it to work, because the documentation says that it emits the error, which should trigger sending the status to the client.

@jonahbron
Copy link
Author

@murgatroid99 Are you aware of an alternative method to send an error from a streaming API?

@murgatroid99
Copy link
Member

In our tests, we just do call.emit('error', status).

@jonahbron
Copy link
Author

Aha, that works perfectly. It would be nice if there was a way to send an error message though. Would it be welcome if I submitted a PR to the tutorial file with an example?

https://grpc.io/docs/tutorials/basic/node.html
https://github.com/grpc/grpc.github.io//edit/master/docs/tutorials/basic/node.md

@murgatroid99
Copy link
Member

Are you having problems sending the error message? I think that code would do it. If it isn't working, you may want to try calling the string details instead of message.

As for the tutorial, that's a bit complicated because we generally prefer to keep our examples aligned across languages, and I don't know if there is currently a plan for cross language error handling examples. There is this repository with some gRPC error examples, so you may want to ask there about adding examples for streaming calls.

@jonahbron
Copy link
Author

@murgatroid99 I'll check out that repo, thank you. It seems that the issue was in part caused by an extra call.end() in my code that was closing the connection before the response could be sent. Thanks!

@lock lock bot locked as resolved and limited conversation to collaborators Sep 29, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants