Skip to content

Commit 9a1d031

Browse files
authored
add regression test capturing need for withCause call (#460)
1 parent bd72a26 commit 9a1d031

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

stub/src/test/java/io/grpc/kotlin/ServerCallsTest.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,4 +1168,56 @@ class ServerCallsTest : AbstractCallsTest() {
11681168
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
11691169
}
11701170

1171+
@Test
1172+
fun testPropagateStackTraceForNonStatusExceptionWithStatusExceptionCause() = runBlocking {
1173+
val thrownStatusCause = CompletableDeferred<Throwable?>()
1174+
1175+
val serverImpl = object : GreeterCoroutineImplBase() {
1176+
override suspend fun sayHello(request: HelloRequest): HelloReply {
1177+
internalServerCall()
1178+
}
1179+
1180+
private fun internalServerCall(): Nothing {
1181+
val exception = Exception("causal exception", Status.INTERNAL.asException())
1182+
thrownStatusCause.complete(exception)
1183+
throw exception
1184+
}
1185+
}
1186+
1187+
val receivedStatusCause = CompletableDeferred<Throwable?>()
1188+
1189+
val interceptor = object : ServerInterceptor {
1190+
override fun <ReqT, RespT> interceptCall(
1191+
call: ServerCall<ReqT, RespT>,
1192+
requestHeaders: Metadata,
1193+
next: ServerCallHandler<ReqT, RespT>
1194+
): ServerCall.Listener<ReqT> =
1195+
next.startCall(
1196+
object : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
1197+
override fun close(status: Status, trailers: Metadata) {
1198+
receivedStatusCause.complete(status.cause)
1199+
super.close(status, trailers)
1200+
}
1201+
},
1202+
requestHeaders
1203+
)
1204+
}
1205+
1206+
val channel = makeChannel(serverImpl, interceptor)
1207+
1208+
val stub = GreeterGrpc.newBlockingStub(channel)
1209+
val clientException = assertThrows<StatusRuntimeException> {
1210+
stub.sayHello(helloRequest(""))
1211+
}
1212+
1213+
// the exception should not propagate to the client
1214+
assertThat(clientException.cause).isNull()
1215+
1216+
assertThat(clientException.status.code).isEqualTo(Status.Code.INTERNAL)
1217+
val statusCause = receivedStatusCause.await()
1218+
// but the exception should propagate to server interceptors, with stack trace intact
1219+
assertThat(statusCause).isEqualTo(thrownStatusCause.await())
1220+
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
1221+
}
1222+
11711223
}

0 commit comments

Comments
 (0)