javagrpcquarkusgrpc-javaquarkus-grpc

Quarkus gRPC ExceptionHandlerProvider does not close response message with the correct status


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.

Repo to reproduce

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).

Error response

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


Solution

  • OK, same discussion -- answered here: