Hi,
I am handling gRPC server-side handler exceptions in an interceptor:
public override async Task<TResponse> UnaryServerHandler<TRequest,
TResponse>( TRequest request, ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
try
{
return await continuation(request, context);
}
catch (Exception ex)
{
LogAndRethrowException(ex);
return null; // keep compiler happy
}
}
The relevant part of LogAndRethrowException looks like this:
s_log.Debug("Unhandled Exception processing gRPC request", ex);
throw new RpcException(new Status( StatusCode.Unknown, "Intercepted
Unhandled: " + ex.Message));
This is working fine. I'm getting the exceptions on the client and can do
the necessary handling I need to do there, plus I'm logging it on the
server.
I now need to modify this to crash the server app, as this is the policy
where I work. However I still need to get the exception on the client side.
Is there any way in the existing gRPC library to hook into (or get some
kind of callback for) the point immediately after the RpcException has been
handled by the gRPC and the response sent down the wire to the client?
(The source code mentions that the cancellationToken should be fired
whenever anything other than StatusCode.OK is returned, but I tried
registering to this and it didn't seem to be the case, at least when
throwing an RpcException)
I do have access to a synchronisation context used by the server end, and
can send a Post to this to have it throw the exception. However this is
probably not reliable since at this point in the interceptor I'm not
actually on this sync context so the server might end up crashed too soon.
(On the other hand, ideally I'd like it to crash immediately after getting
the exception response back to the client, and the sync context may have
other stuff queued up...)
I've been looking for hooks in the ServerCallContext, or trying to think of
ways of using the continuation creatively, but I can't see any good
solution.
I did have a look at the code which actually handles the exception and
sends the status, to see if there were any hints there.
In ServerCallHandler.cs, I had a look at the HandleCall method.
The finishedTask (which is set to set to asyncCall.ServerSideCallAsync() at
the start) looked promising. I haven't looked into it properly, but as it's
awaited at the end, could this provide a way somehow?
(And, a bit of a long shot... but it looks like, with java gRPC, that you
can 'send' the exception back to the client by
calling responseObserver.onError - is there anything similar in C# gRPC
which I could somehow use as an alternative to just throwing
the RpcException to get the appropriate response back?)
cheers,
Pete Beech
--
You received this message because you are subscribed to the Google Groups
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/grpc-io/c6f78ab1-23d3-480b-a1b3-3f0e54a0f7ebn%40googlegroups.com.