grpc-kotlin icon indicating copy to clipboard operation
grpc-kotlin copied to clipboard

No way to create global Exception handler for all calls

Open avalsa opened this issue 3 years ago • 1 comments
trafficstars

Goal to create global exception handler to process all uncaught exceptions. Consider modification of examples/helloworld :


package io.grpc.examples.helloworld

import io.grpc.Metadata
import io.grpc.Server
import io.grpc.ServerBuilder
import io.grpc.ServerCall
import io.grpc.kotlin.CoroutineContextServerInterceptor
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlin.coroutines.CoroutineContext

class HelloWorldServer(private val port: Int) {
    val server: Server = ServerBuilder
        .forPort(port)
        .intercept(ExceptionIntercepter())
        .addService(HelloWorldService())
        .build()

    fun start() {
        server.start()
        println("Server started, listening on $port")
        Runtime.getRuntime().addShutdownHook(
            Thread {
                println("*** shutting down gRPC server since JVM is shutting down")
                [email protected]()
                println("*** server shut down")
            }
        )
    }

    private fun stop() {
        server.shutdown()
    }

    fun blockUntilShutdown() {
        server.awaitTermination()
    }

    internal class HelloWorldService : GreeterGrpcKt.GreeterCoroutineImplBase() {
        override suspend fun sayHello(request: HelloRequest): HelloReply {
            throw RuntimeException("problem")
        }
    }
}

class ExceptionIntercepter : CoroutineContextServerInterceptor() {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("CoroutineExceptionHandler got $exception")
    }
    override fun coroutineContext(call: ServerCall<*, *>, headers: Metadata): CoroutineContext {
        return handler
    }
}

fun main() {
    val port = System.getenv("PORT")?.toInt() ?: 50051
    val server = HelloWorldServer(port)
    server.start()
    server.blockUntilShutdown()
}

The problem that handler never called. As I understood from code the problem in ServerCalls::serverCallListener() runCatching that catches all exceptions. How can I achieve this goal? I think about moving around runCatching block. Any thoughts?

avalsa avatar Nov 20 '22 18:11 avalsa