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: