I have a Quarkus gRPC server (reactive with Mutiny) and I want to customize the response status if an exception is thrown on the server side service.
By default, when an exception is thrown, the server responds a gRPC status UNKNOWN
. When some exception is thrown, I want to respond with status INTERNAL
(or others).
To do this, I used the ExceptionHandlerProvider
(doc). The problem is that the method ExceptionHandler::handleException
is never called (but ExceptionHandlerProvider::transform
is).
Code simplified, real code here
@ApplicationScoped
public class HelloExceptionHandlerProvider implements ExceptionHandlerProvider {
@Override
public <ReqT, RespT> ExceptionHandler<ReqT, RespT> createHandler(ServerCall.Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
System.out.println("HelloExceptionHandlerProvider::createHandler");
return new HelloExceptionHandler<>(listener, serverCall, metadata);
}
@Override
public Throwable transform(final Throwable throwable) {
return new StatusException().status(Status.INTERNAL); // TODO: transform the throwable to status exception
}
protected static class HelloExceptionHandler<I, O> extends ExceptionHandler<I, O> {
public HelloExceptionHandler(ServerCall.Listener<I> listener, ServerCall<I, O> call, Metadata metadata) {
super(listener, call, metadata);
}
@Override
protected void handleException(Throwable throwable, ServerCall<I, O> call, Metadata metadata) {
// This is never called!
StatusException ex = (StatusException) throwable;
call.close(ex.getStatus(), ex.getTrailers());
}
}
}
So on the client side, when an exception is thrown, the response status is still UNKNOWN
(should be INTERNAL)
but there is a grpc-status
metadata value with value 13 (INTERNAL
code value).
In the logs, everything is fine except that the missing handleException
call :
HelloExceptionHandlerProvider::createHandler
HelloExceptionHandler::constructor
HelloExceptionHandlerProvider::transform - Should exit with status INTERNAL
Do I miss something here?
Another weird thing is that if I comment the metadata.put(Metadata.Key.of("hello-error-code", Metadata.ASCII_STRING_MARSHALLER), ex.getCode());
line then the status is INTERNAL
as expected. It seems that adding trailer metadata cause the response to fail with UNKNOWN
status.
Edit: It seems fine when using the Quarkus gRPC client. This weird behavior is seen in Postman interface. See https://github.com/quarkusio/quarkus/discussions/31110#discussioncomment-4956272
OK, same discussion -- answered here: