-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot catch Exception from Server Stub #141
Comments
Have you read the documentation of |
yes I read the docs and was the original reason I was attempting to install the exception handler inside a gRPC interceptor. Maybe I should take a step back to explain what I am trying to do. I don't want to wrap every gRPC service impl with a try-catch to log exceptions. Rather install an exception handler in an interceptor so it applies to every gRPC service. I originally tried doing it inside of a I'm basically using a version of this grpc/grpc-java#1552 (comment) |
I think you could use a |
Implement |
I got really stuck on this as well and was about to switch to grpc-java, but then saw how
|
@jonpeterson Thanks for sharing that! I was trying to use In the implementation you shared, is the package com.yourproject
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 mu.KotlinLogging
import javax.inject.Singleton
private val logger = KotlinLogging.logger {}
/**
* Log all exceptions thrown from gRPC endpoints, and adjust Status for known exceptions.
*/
@Singleton
class ExceptionInterceptor : ServerInterceptor {
/**
* When closing a gRPC call, extract any error status information to top-level fields. Also
* log the cause of errors.
*/
private class ExceptionTranslatingServerCall<ReqT, RespT>(
delegate: ServerCall<ReqT, RespT>
) : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(delegate) {
override fun close(status: Status, trailers: Metadata) {
if (status.isOk) {
return super.close(status, trailers)
}
val cause = status.cause
var newStatus = status
logger.error(cause) { "Error handling gRPC endpoint." }
if (status.code == Status.Code.UNKNOWN) {
val translatedStatus = when (cause) {
is IllegalArgumentException -> Status.INVALID_ARGUMENT
is IllegalStateException -> Status.FAILED_PRECONDITION
else -> Status.UNKNOWN
}
newStatus = translatedStatus.withDescription(cause?.message).withCause(cause)
}
super.close(newStatus, 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), headers)
}
} |
I am attempting to install a default Exception handler for our gRPC server stubs. I have tried using both a java gRPC interceptor and coroutine exception handlers, but nothing seems to work. The following code snippet below replicates the issue.
Using the debugger I traced the issue to here
https://github.com/grpc/grpc-kotlin/blob/master/stub/src/main/java/io/grpc/kotlin/ServerCalls.kt#L229
It seems like the CoroutineContext provided to the stub is not used in the Flow that dispatches requests.
I'm fairly new to coroutines so maybe I'm doing something wrong.
The text was updated successfully, but these errors were encountered: