gRPC stream error handling

6,078 views
Skip to first unread message

Glyn Normington

unread,
Feb 13, 2018, 9:05:50 AM2/13/18
to grpc.io
I'm trying to decide how to handle stream errors correctly, both in the client and in the server. My working assumption, in Go, is that io.EOF indicates a normal termination and that all other errors are abnormal and permanent, but I'd like to check that assumption.

It would be great to know which gRPC errors are permanent and which, if any, are transient. The Go Stream interface talks about streams being "done" or "aborted" (both of which sound like permanent states), but without defining these terms further.

The available example code isn't particularly useful as it's not clear which parts are normative.

The gRPC documentation has a section on error handling, but this doesn't describe which errors are permanent and which are transient. It's not even clear how the status codes described map to language-specific error values. For instance, which value(s) corresponds to io.EOF (surely a permanent error!) in Go?

Please could someone offer some definitive information?

Regards,
Glyn



Doug Fawley

unread,
Feb 27, 2018, 12:18:06 PM2/27/18
to grpc.io
Client-side, io.EOF is returned directly from grpc-go steram.Send() calls when the server closes the stream.  At that point, Recv() should be called until it returns a non-nil error to receive the server's messages and eventually the status.  If io.EOF is returned by Recv(), that indicates a success; otherwise that is the final status of the RPC.  All errors are permanent from the standpoint of that stream -- subsequent streams are possible using the same client, even if it is a connection error, as the client automatically attempts to reconnect.  Make sure you always call Recv() on the stream until you get a non-nil error or cancel the context used when creating the stream, or else a goroutine and other resources will be leaked.

Let me know if you have any further questions.

Thanks,
Doug

stu...@stuartbishop.net

unread,
Mar 5, 2018, 2:41:14 AM3/5/18
to grpc.io


On Wednesday, February 28, 2018 at 12:18:06 AM UTC+7, Doug Fawley wrote:
Client-side, io.EOF is returned directly from grpc-go steram.Send() calls when the server closes the stream.  At that point, Recv() should be called until it returns a non-nil error to receive the server's messages and eventually the status.  If io.EOF is returned by Recv(), that indicates a success; otherwise that is the final status of the RPC.  All errors are permanent from the standpoint of that stream -- subsequent streams are possible using the same client, even if it is a connection error, as the client automatically attempts to reconnect.  Make sure you always call Recv() on the stream until you get a non-nil error or cancel the context used when creating the stream, or else a goroutine and other resources will be leaked.

Let me know if you have any further questions.

Just to clarify, should with single directional streaming do we need to call RecvMsg after stream.Send returns io.EOF, to get any failure from the server? Only bidirectional streams have both a Send and Recv method.


Jh Shi

unread,
Sep 26, 2022, 6:42:40 AM9/26/22
to grpc.io
Whatever in client side or server side, you could call 'CloseSend' then cancel the context in grpc-go as a normal termination or cancel the context without calling 'CloseSend' as an error abort. But on the another side, it's difficult to clear what actual error causing this abort.
Reply all
Reply to author
Forward
0 new messages