Handling Exceptions and status codes
MagicOnion allows you to return the result of server processing as a status code separately from the return value. This is similar to HTTP status codes or gRPC status codes. You can also include application-specific status codes in these status codes.
Notifying the client of the status code from the server
If you want to return a custom status code from the server to the client, you can use ReturnStatusException
.
public Task SendMessageAsync(string message)
{
if (message.Contains("foo"))
{
//
throw new ReturnStatusException((Grpc.Core.StatusCode)MyStatusCode.SomethingWentWrong, "invalid");
}
// ....
The ReturnStatusException
has an Grpc.Core.StatusCode
enumeration type as the status code, and this value is notified to the client. To return a custom status code for the application, cast your own int
value or enumeration type to the Grpc.Core.StatusCode
enumeration type.
If you are performance-centric and want to avoid throwing exceptions, you can use CallContext.Status
(ServiceContext.CallContext.Status
) to set the status directly.
Exception handling on the client
All exceptions that occur when a method is called on the client are received as a RpcException
of gRPC.
var client = MagicOnionClient.Create<IGreeterService>(channel);
try
{
var result = await client.SayHelloAsync("Alice", 18);
}
catch (RpcException ex)
{
// handle exception ...
if (((MyStatusCode)ex.Status.StatusCode) == MyStatusCode.SomethingWentWrong)
{
// ...
}
}
If there is a problem with the network, RpcException
is thrown with StatusCode.Unavailable
. You can investigate the detailed error content with the InnerException
property.
Unhandled exceptions on the server
If an unhandled exception is thrown during a method call on the server, except for ReturnStatusException
, the client treats it as an RpcException
with StatusCode.Unknown
.
If MagicOnionOption.IsReturnExceptionStackTraceInErrorDetail
is true
, the client can receive the stack trace of the server exception. This is very useful for debugging, but it has a critical security issue, so it should only be enabled in debug builds.