@@ -1168,4 +1168,56 @@ class ServerCallsTest : AbstractCallsTest() {
1168
1168
assertThat(statusCause!! .stackTraceToString()).contains(" internalServerCall" )
1169
1169
}
1170
1170
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
+
1171
1223
}
0 commit comments