Skip to content

Commit

Permalink
add regression test capturing need for withCause call (#460)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewparmet committed Nov 17, 2023
1 parent bd72a26 commit 9a1d031
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions stub/src/test/java/io/grpc/kotlin/ServerCallsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1168,4 +1168,56 @@ class ServerCallsTest : AbstractCallsTest() {
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
}

@Test
fun testPropagateStackTraceForNonStatusExceptionWithStatusExceptionCause() = runBlocking {
val thrownStatusCause = CompletableDeferred<Throwable?>()

val serverImpl = object : GreeterCoroutineImplBase() {
override suspend fun sayHello(request: HelloRequest): HelloReply {
internalServerCall()
}

private fun internalServerCall(): Nothing {
val exception = Exception("causal exception", Status.INTERNAL.asException())
thrownStatusCause.complete(exception)
throw exception
}
}

val receivedStatusCause = CompletableDeferred<Throwable?>()

val interceptor = object : ServerInterceptor {
override fun <ReqT, RespT> interceptCall(
call: ServerCall<ReqT, RespT>,
requestHeaders: Metadata,
next: ServerCallHandler<ReqT, RespT>
): ServerCall.Listener<ReqT> =
next.startCall(
object : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
override fun close(status: Status, trailers: Metadata) {
receivedStatusCause.complete(status.cause)
super.close(status, trailers)
}
},
requestHeaders
)
}

val channel = makeChannel(serverImpl, interceptor)

val stub = GreeterGrpc.newBlockingStub(channel)
val clientException = assertThrows<StatusRuntimeException> {
stub.sayHello(helloRequest(""))
}

// the exception should not propagate to the client
assertThat(clientException.cause).isNull()

assertThat(clientException.status.code).isEqualTo(Status.Code.INTERNAL)
val statusCause = receivedStatusCause.await()
// but the exception should propagate to server interceptors, with stack trace intact
assertThat(statusCause).isEqualTo(thrownStatusCause.await())
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
}

}

0 comments on commit 9a1d031

Please sign in to comment.