[C#] Requirement of valid response object when status in non-OK in unary server call

227 views
Skip to first unread message

Joseph Vaughan

unread,
May 14, 2018, 6:03:40 AM5/14/18
to grpc.io
Hi,

I'm looking to use the interceptor functionality to abort or cleanly cancel RPCs based on some logic. Right now I'm happy to use the built in gRPC status codes as they suit my needs. I can see in C# how setting the status and returning a response prior to invoking the continuation would work, however I cannot see how to return a null / empty response as right now this will throw an exception when serializing.

I can see there has been some discussion for other languages on this topic here:
  1. https://github.com/grpc/grpc/issues/12824
  2. https://github.com/grpc/grpc/issues/12826

In Issue #12826 Mehrdad Afshari said the following which is identical to my situation:


There was at least one case where the user wants to return a result from an interceptor, not the handler, and there was no generic way to figure out what the type of the correct type to return from the handler was in the interceptor to construct an empty object out of. That is the prime motivator for moving this forward.


I haven't had much luck finding any discussion on this topic for the C# library. Is there any plans for similar support? A naive look at the code by me seems that the responseWithFlags variable could be null if the response is null, but I don't fully understand the implications of that.

Thanks,
Joseph.

Benjamin Krämer

unread,
May 14, 2018, 7:28:02 AM5/14/18
to grpc.io
One workaround that I know works is to throw an RpcException:
throw new RpcException(new Status(StatusCode.Aborted, "Interceptor aborted"));


Benjamin Krämer

unread,
May 14, 2018, 7:55:57 AM5/14/18
to grpc.io
Made some tests myself and it seems that throwing the exception is the only half-way good way right now. Returning null results in the status being overwritten with "Cancelled". Another way that I found working but don't really like is creating an instance using the Activator:
public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
{
    context
.Status = new Status(StatusCode.Aborted, "Interceptor aborted");
   
return Task.FromResult(Activator.CreateInstance<TResponse>());
}

The problem is, that TRequest and TResponse are only restricted as class and not as IMessage. If it would have been limited to "IMessage, new()" it would have been easier to just use "new TResponse()".

Joseph Vaughan

unread,
May 15, 2018, 2:48:12 AM5/15/18
to grpc.io
Throwing the exception is the solution I'm using currently, however I was previously advised that I can avoid that by setting the status and returning: https://groups.google.com/forum/#!topic/grpc-io/OXKLky8p9f8

Thank you for your tests, it's odd that the status is overwritten with "Cancelled". I know the C# Interceptors API is still fairly new, so I hope we'll see some changes to this functionality.
Reply all
Reply to author
Forward
0 new messages