Advice exception handling not working with grpc-kotlin coroutines
See original GitHub issueThe context
The plan is to implement the server stub with coroutine support from grpc-kotlin and exception handling via an exception handler advice.
The bug
While the registered advice picks up exceptions when implementing the normal blocking server stub (*ImplBase
), when using coroutines support (*CoroutineImplBase
) the exceptions are not handled and a Status.UNKNOWN is returned regardless.
Stacktrace and logs
Is there a stacktrace or a hint in the logs? (very important) Screenshots work as well, but don’t screenshot your logs.
Steps to Reproduce
Steps to reproduce the behavior:
- Implement server stubs for the CoroutineImplBase
- Implement and register GrpcAdvice
- Force some exception to be thrown
- Verify that advice methods are not reached
The application’s environment
Which versions do you use?
- Spring (boot): 2.4.0
- grpc-kotlin: 1.0.0
- grpc-spring-boot-starter: 2.11.0
Additional context
There seems to be a difference between the regular implementation where onHalfClose
is called (and thus exception is handled) and the coroutine implementation.
To go around this, I quickly created a hacky interceptor like so:
import io.grpc.ForwardingServerCall
import io.grpc.Metadata
import io.grpc.ServerCall
import io.grpc.ServerCallHandler
import io.grpc.ServerInterceptor
import io.grpc.Status
import io.grpc.StatusException
import net.devh.boot.grpc.server.advice.GrpcAdviceExceptionHandler
@GrpcGlobalServerInterceptor
class ExceptionHandlingInterceptor(private val handler: GrpcAdviceExceptionHandler) : ServerInterceptor {
private class ExceptionTranslatingServerCall<ReqT, RespT>(
delegate: ServerCall<ReqT, RespT>,
private val handler: GrpcAdviceExceptionHandler
) : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(delegate) {
override fun close(status: Status, trailers: Metadata) {
if (status.isOk) {
return super.close(status, trailers)
}
val problemStatus = handler.handleThrownException(status.cause) as StatusException
super.close(problemStatus.status, trailers)
}
}
override fun <ReqT : Any?, RespT : Any?> interceptCall(call: ServerCall<ReqT, RespT>?, headers: Metadata?, next: ServerCallHandler<ReqT, RespT>?): ServerCall.Listener<ReqT> {
return next!!.startCall(ExceptionTranslatingServerCall(call!!, handler), headers)
}
}
I haven’t delved deep into the underlying issue, so it can be a problem of the grpc-kotlin-stub:1.0.0
I’m using
Issue Analytics
- State:
- Created 2 years ago
- Comments:11
Definitely this year. Most likely in November. I can try to push the release at bit.
It really seems like a bug in grpc-kotlin, related issues: grpc/grpc-kotlin#141 and grpc/grpc-kotlin#184