Skip to content

Commit 0752d7e

Browse files
committed
Merge branch 'master' into kt_jvm_proto_helper
2 parents bc7e4ed + b8d6452 commit 0752d7e

File tree

9 files changed

+205
-21
lines changed

9 files changed

+205
-21
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
## Change Log
22

3+
### 1.4.1
4+
5+
#### Changes
6+
7+
* fix(ServerCalls): Fix regression in Status cause for exceptions thrown by implementations by @andrewparmet in https://github.com/grpc/grpc-kotlin/pull/456
8+
* Bazel: update to use guava 32.0.1 consistently. by @brettchabot in https://github.com/grpc/grpc-kotlin/pull/436
9+
* Bump composeVersion from 1.5.1 to 1.5.2 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/438
10+
* Bump org.gradle.test-retry from 1.5.5 to 1.5.6 by @dependabot in https://github.com/grpc/grpc-kotlin/pull/439
11+
* Bump androidx.activity:activity-compose from 1.7.2 to 1.8.0 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/441
12+
* Bump composeVersion from 1.5.2 to 1.5.3 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/440
13+
* Bump org.jetbrains.dokka from 1.9.0 to 1.9.10 by @dependabot in https://github.com/grpc/grpc-kotlin/pull/446
14+
* Bump org.jlleitschuh.gradle.ktlint from 11.6.0 to 11.6.1 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/443
15+
* Bump com.google.guava:guava from 32.1.2-jre to 32.1.3-jre by @dependabot in https://github.com/grpc/grpc-kotlin/pull/445
16+
* FIXED: Missing double quotes in compiler docs leading to error. by @prodbyola in https://github.com/grpc/grpc-kotlin/pull/453
17+
* Bump androidx.activity:activity-compose from 1.8.0 to 1.8.1 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/457
18+
* Bump composeVersion from 1.5.3 to 1.5.4 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/447
19+
* Bump jvm from 1.9.10 to 1.9.20 in /examples by @dependabot in https://github.com/grpc/grpc-kotlin/pull/450
20+
* Bump org.junit.jupiter:junit-jupiter-engine from 5.10.0 to 5.10.1 by @dependabot in https://github.com/grpc/grpc-kotlin/pull/454
21+
22+
#### New Contributors
23+
* @brettchabot made their first contribution in https://github.com/grpc/grpc-kotlin/pull/436
24+
* @prodbyola made their first contribution in https://github.com/grpc/grpc-kotlin/pull/453
25+
* @andrewparmet made their first contribution in https://github.com/grpc/grpc-kotlin/pull/456
26+
27+
**Full Changelog**: https://github.com/grpc/grpc-kotlin/compare/v1.4.0...v1.4.1
28+
29+
330
### 1.4.0
431

532
#### Changes

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
55
plugins {
66
kotlin("jvm") version "1.8.0" apply false
77
id("com.google.protobuf") version "0.9.4" apply false
8-
id("org.gradle.test-retry") version "1.5.5"
8+
id("org.gradle.test-retry") version "1.5.6"
99
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
1010
}
1111

1212
group = "io.grpc"
13-
version = "1.4.0" // CURRENT_GRPC_KOTLIN_VERSION
13+
version = "1.4.1" // CURRENT_GRPC_KOTLIN_VERSION
1414

1515
ext["grpcVersion"] = "1.57.2"
1616
ext["protobufVersion"] = "3.24.1"

compiler/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ that just runs that `jar`, for example create a file named `protoc-gen-grpc-kotl
178178
#!/usr/bin/env sh
179179
180180
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
181-
java -jar $DIR/protoc-gen-grpc-kotlin-SOME_VERSION-jdk8.jar "$@
181+
java -jar $DIR/protoc-gen-grpc-kotlin-SOME_VERSION-jdk8.jar "$@"
182182
```
183183

184184
Then make that file executable:

compiler/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ dependencies {
1818

1919
// Misc
2020
implementation(kotlin("reflect"))
21-
implementation("com.squareup:kotlinpoet:1.14.2")
21+
implementation("com.squareup:kotlinpoet:1.15.1")
2222
implementation("com.google.truth:truth:1.1.5")
2323

2424
// Testing
2525
testImplementation("junit:junit:4.13.2")
26-
testImplementation("com.google.guava:guava:32.1.2-jre")
26+
testImplementation("com.google.guava:guava:32.1.3-jre")
2727
testImplementation("com.google.jimfs:jimfs:1.3.0")
2828
testImplementation("com.google.protobuf:protobuf-gradle-plugin:0.9.4")
2929
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
30-
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.0")
30+
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.1")
3131
testImplementation("org.mockito:mockito-core:4.11.0")
3232
}
3333

examples/android/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ plugins {
33
kotlin("android")
44
}
55

6-
val composeVersion = "1.5.1"
7-
val composeCompilerVersion = "1.5.3"
6+
val composeVersion = "1.5.4"
7+
val composeCompilerVersion = "1.5.4"
88

99
dependencies {
1010
implementation(project(":stub-android"))
11-
implementation("androidx.activity:activity-compose:1.7.2")
11+
implementation("androidx.activity:activity-compose:1.8.1")
1212
implementation("androidx.compose.foundation:foundation-layout:$composeVersion")
1313
implementation("androidx.compose.material:material:$composeVersion")
1414
implementation("androidx.compose.runtime:runtime:$composeVersion")

examples/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
plugins {
22
id("com.android.application") version "8.1.1" apply false
33
id("com.google.protobuf") version "0.9.4" apply false
4-
kotlin("jvm") version "1.9.10" apply false
5-
id("org.jlleitschuh.gradle.ktlint") version "11.6.0" apply false
4+
kotlin("jvm") version "1.9.20" apply false
5+
id("org.jlleitschuh.gradle.ktlint") version "11.6.1" apply false
66
}
77

88
// todo: move to subprojects, but how?
99
ext["grpcVersion"] = "1.57.2"
10-
ext["grpcKotlinVersion"] = "1.4.0" // CURRENT_GRPC_KOTLIN_VERSION
10+
ext["grpcKotlinVersion"] = "1.4.1" // CURRENT_GRPC_KOTLIN_VERSION
1111
ext["protobufVersion"] = "3.24.1"
1212
ext["coroutinesVersion"] = "1.7.3"
1313

stub/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import org.jetbrains.dokka.gradle.DokkaTask
33
import java.net.URL
44

55
plugins {
6-
id("org.jetbrains.dokka") version "1.9.0"
6+
id("org.jetbrains.dokka") version "1.9.10"
77
}
88

99
repositories {
@@ -27,7 +27,7 @@ dependencies {
2727

2828
// Testing
2929
testImplementation("junit:junit:4.13.2")
30-
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.0")
30+
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.1")
3131
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-debug:${rootProject.ext["coroutinesVersion"]}")
3232
testImplementation("com.google.truth.extensions:truth-proto-extension:1.1.5")
3333
testImplementation("io.grpc:grpc-protobuf:${rootProject.ext["grpcVersion"]}")

stub/src/main/java/io/grpc/kotlin/ServerCalls.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,20 @@ import io.grpc.ServerCallHandler
2626
import io.grpc.ServerMethodDefinition
2727
import io.grpc.Status
2828
import io.grpc.StatusException
29+
import io.grpc.StatusRuntimeException
2930
import kotlinx.coroutines.CancellationException
3031
import kotlinx.coroutines.CoroutineScope
3132
import kotlinx.coroutines.cancel
3233
import kotlinx.coroutines.channels.Channel
3334
import kotlinx.coroutines.channels.onFailure
3435
import kotlinx.coroutines.flow.Flow
35-
import kotlinx.coroutines.flow.collect
3636
import kotlinx.coroutines.flow.flow
3737
import kotlinx.coroutines.flow.map
3838
import kotlinx.coroutines.launch
3939
import kotlinx.coroutines.sync.Mutex
4040
import kotlinx.coroutines.sync.withLock
4141
import java.util.concurrent.atomic.AtomicBoolean
4242
import kotlin.coroutines.CoroutineContext
43-
import kotlinx.coroutines.channels.onFailure
4443
import io.grpc.Metadata as GrpcMetadata
4544

4645
/**
@@ -262,6 +261,7 @@ object ServerCalls {
262261
val closeStatus = when (failure) {
263262
null -> Status.OK
264263
is CancellationException -> Status.CANCELLED.withCause(failure)
264+
is StatusException, is StatusRuntimeException -> Status.fromThrowable(failure)
265265
else -> Status.fromThrowable(failure).withCause(failure)
266266
}
267267
val trailers = failure?.let { Status.trailersFromThrowable(it) } ?: GrpcMetadata()

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

Lines changed: 162 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ import com.google.common.truth.Truth.assertThat
2020
import com.google.common.truth.extensions.proto.ProtoTruth.assertThat
2121
import io.grpc.*
2222
import io.grpc.examples.helloworld.GreeterGrpc
23-
import io.grpc.examples.helloworld.GreeterGrpcKt
2423
import io.grpc.examples.helloworld.HelloReply
2524
import io.grpc.examples.helloworld.HelloRequest
2625
import io.grpc.examples.helloworld.GreeterGrpcKt.GreeterCoroutineStub
2726
import io.grpc.examples.helloworld.GreeterGrpcKt.GreeterCoroutineImplBase
28-
import io.grpc.stub.StreamObserver
2927
import kotlinx.coroutines.CompletableDeferred
3028
import kotlinx.coroutines.CoroutineName
3129
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -1015,15 +1013,18 @@ class ServerCallsTest : AbstractCallsTest() {
10151013
}
10161014

10171015
@Test
1018-
fun testStatusExceptionPropagatesStack() = runBlocking {
1016+
fun testPropagateStackTraceForStatusException() = runBlocking {
1017+
val thrownStatusCause = CompletableDeferred<Throwable?>()
10191018

10201019
val serverImpl = object : GreeterCoroutineImplBase() {
10211020
override suspend fun sayHello(request: HelloRequest): HelloReply {
10221021
internalServerCall()
10231022
}
10241023

10251024
private fun internalServerCall(): Nothing {
1026-
throw StatusException(Status.INTERNAL)
1025+
val exception = Exception("causal exception")
1026+
thrownStatusCause.complete(exception)
1027+
throw Status.INTERNAL.withCause(exception).asException()
10271028
}
10281029
}
10291030

@@ -1059,7 +1060,163 @@ class ServerCallsTest : AbstractCallsTest() {
10591060
assertThat(clientException.status.code).isEqualTo(Status.Code.INTERNAL)
10601061
val statusCause = receivedStatusCause.await()
10611062
// but the exception should propagate to server interceptors, with stack trace intact
1062-
assertThat(statusCause).isNotNull()
1063+
assertThat(statusCause).isEqualTo(thrownStatusCause.await())
1064+
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
1065+
}
1066+
1067+
@Test
1068+
fun testPropagateStackTraceForStatusRuntimeException() = runBlocking {
1069+
val thrownStatusCause = CompletableDeferred<Throwable?>()
1070+
1071+
val serverImpl = object : GreeterCoroutineImplBase() {
1072+
override suspend fun sayHello(request: HelloRequest): HelloReply {
1073+
internalServerCall()
1074+
}
1075+
1076+
private fun internalServerCall(): Nothing {
1077+
val exception = Exception("causal exception")
1078+
thrownStatusCause.complete(exception)
1079+
throw Status.INTERNAL.withCause(exception).asRuntimeException()
1080+
}
1081+
}
1082+
1083+
val receivedStatusCause = CompletableDeferred<Throwable?>()
1084+
1085+
val interceptor = object : ServerInterceptor {
1086+
override fun <ReqT, RespT> interceptCall(
1087+
call: ServerCall<ReqT, RespT>,
1088+
requestHeaders: Metadata,
1089+
next: ServerCallHandler<ReqT, RespT>
1090+
): ServerCall.Listener<ReqT> =
1091+
next.startCall(
1092+
object : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
1093+
override fun close(status: Status, trailers: Metadata) {
1094+
receivedStatusCause.complete(status.cause)
1095+
super.close(status, trailers)
1096+
}
1097+
},
1098+
requestHeaders
1099+
)
1100+
}
1101+
1102+
val channel = makeChannel(serverImpl, interceptor)
1103+
1104+
val stub = GreeterGrpc.newBlockingStub(channel)
1105+
val clientException = assertThrows<StatusRuntimeException> {
1106+
stub.sayHello(helloRequest(""))
1107+
}
1108+
1109+
// the exception should not propagate to the client
1110+
assertThat(clientException.cause).isNull()
1111+
1112+
assertThat(clientException.status.code).isEqualTo(Status.Code.INTERNAL)
1113+
val statusCause = receivedStatusCause.await()
1114+
// but the exception should propagate to server interceptors, with stack trace intact
1115+
assertThat(statusCause).isEqualTo(thrownStatusCause.await())
1116+
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
1117+
}
1118+
1119+
@Test
1120+
fun testPropagateStackTraceForNonStatusException() = runBlocking {
1121+
val thrownStatusCause = CompletableDeferred<Throwable?>()
1122+
1123+
val serverImpl = object : GreeterCoroutineImplBase() {
1124+
override suspend fun sayHello(request: HelloRequest): HelloReply {
1125+
internalServerCall()
1126+
}
1127+
1128+
private fun internalServerCall(): Nothing {
1129+
val exception = Exception("causal exception")
1130+
thrownStatusCause.complete(exception)
1131+
throw exception
1132+
}
1133+
}
1134+
1135+
val receivedStatusCause = CompletableDeferred<Throwable?>()
1136+
1137+
val interceptor = object : ServerInterceptor {
1138+
override fun <ReqT, RespT> interceptCall(
1139+
call: ServerCall<ReqT, RespT>,
1140+
requestHeaders: Metadata,
1141+
next: ServerCallHandler<ReqT, RespT>
1142+
): ServerCall.Listener<ReqT> =
1143+
next.startCall(
1144+
object : ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
1145+
override fun close(status: Status, trailers: Metadata) {
1146+
receivedStatusCause.complete(status.cause)
1147+
super.close(status, trailers)
1148+
}
1149+
},
1150+
requestHeaders
1151+
)
1152+
}
1153+
1154+
val channel = makeChannel(serverImpl, interceptor)
1155+
1156+
val stub = GreeterGrpc.newBlockingStub(channel)
1157+
val clientException = assertThrows<StatusRuntimeException> {
1158+
stub.sayHello(helloRequest(""))
1159+
}
1160+
1161+
// the exception should not propagate to the client
1162+
assertThat(clientException.cause).isNull()
1163+
1164+
assertThat(clientException.status.code).isEqualTo(Status.Code.UNKNOWN)
1165+
val statusCause = receivedStatusCause.await()
1166+
// but the exception should propagate to server interceptors, with stack trace intact
1167+
assertThat(statusCause).isEqualTo(thrownStatusCause.await())
1168+
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
1169+
}
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())
10631220
assertThat(statusCause!!.stackTraceToString()).contains("internalServerCall")
10641221
}
10651222

0 commit comments

Comments
 (0)