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?