1

I have two gRPC endpoints available, and a ServerInterceptor which should intercept exceptions when thrown.

The gRPC service is defined as following:

@GrpcService
public class AccountsResource implements AccountsApiService {

    @Inject
    AccountsService accountsService;

    @Override
    public Uni<GetTppPlatformGroupIdResponse> getTppPlatformGroupId(Empty request) {
        Context.Key<String> tppIamClientIdKey = Constant.TPP_IAM_CLIENT_ID_CONTEXT_KEY;
        String tppIamClientId = tppIamClientIdKey.get(Context.current());

        return Uni.createFrom().item(() -> accountsService.getTppPlatformGroupIdResponse(tppIamClientId))
                .runSubscriptionOn(Infrastructure.getDefaultExecutor());
    }
}

The gRPC service uses SmallRye Mutiny Reactive for handling of the requests.

Other posts explained that the onHalfClose method should be overridden and a try/catch block inserted to catch custom exceptions, which are then mappen to the StatusRuntimeException gRPC can work with. I tried the following:

@ApplicationScoped
@GlobalInterceptor
public class ExceptionInterceptor implements ServerInterceptor {

    private static final Logger LOG = LogManager.getLogger(ExceptionInterceptor.class);

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
        ServerCall.Listener<ReqT> listener = serverCallHandler.startCall(serverCall, metadata);
        return new ExceptionHandlingServerCallListener<>(listener, serverCall, metadata);
    }

    private class ExceptionHandlingServerCallListener<ReqT, RespT> extends ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT> {
        private ServerCall<ReqT, RespT> serverCall;
        private Metadata metadata;

        ExceptionHandlingServerCallListener(ServerCall.Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
            super(listener);
            this.serverCall = serverCall;
            this.metadata = metadata;
        }

        @Override
        public void onHalfClose() {
            try {
                super.onHalfClose();
            } catch (Throwable ex) {
                handleException(ex, serverCall, metadata);
            }
        }

        @Override
        public void onReady() {
            try {
                super.onReady();
            } catch (Throwable ex) {
                handleException(ex, serverCall, metadata);
            }
        }
    }

The handleException method maps the Throwable to the StatusRuntimeException and throws the StatusRuntimeException.

So far so good, and when running the application and simulating a custom exception the ExceptionInterceptor does enter the onHalfClose method. It does not however, go into the catch block even though an exception has been thrown. This error message is logged to the console instead:

2022-01-24 12:07:36,232 WARN [io.qua.grp.run.ServerCalls] (executor-thread-0) gRPC service threw an exception other than StatusRuntimeException

How can this be fixed?

  • I'm facing the same issue and I'm stuck too. Did you find anything? They added the https://quarkus.io/guides/grpc-service-consumption#custom-exception-handling in v2.16.0 we couldn't make it work on the server side. – Junior Dussouillez Feb 10 '23 at 10:46

1 Answers1

-1

use this https://github.com/grpc/grpc-kotlin/issues/141, it is in kotlin but it is possible to adapt to java.

xaverinho
  • 9
  • 2
  • A link to a potential solution is always welcome, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. See https://meta.stackexchange.com/help/how-to-answer – schrom Jan 27 '22 at 13:36