Skip to content

Commit

Permalink
Reject suspend function with Call return type (#4013)
Browse files Browse the repository at this point in the history
  • Loading branch information
Goooler authored Dec 18, 2023
1 parent 8ce895d commit ad84303
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
21 changes: 21 additions & 0 deletions retrofit/kotlin-test/src/test/java/retrofit2/KotlinSuspendTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class KotlinSuspendTest {
@Path("b") b: String,
@Path("c") c: String
): String

@GET("/") suspend fun bodyWithCallType(): Call<String>
}

@Test fun body() {
Expand Down Expand Up @@ -353,6 +355,25 @@ class KotlinSuspendTest {
}
}

@Test fun rejectCallReturnTypeWhenUsingSuspend() {
val retrofit = Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(ToStringConverterFactory())
.build()
val example = retrofit.create(Service::class.java)

try {
runBlocking { example.bodyWithCallType() }
fail()
} catch (e: IllegalArgumentException) {
assertThat(e).hasMessage(
"Suspend functions should not return Call, as they already execute asynchronously.\n" +
"Change its return type to class java.lang.String\n" +
" for method Service.bodyWithCallType"
)
}
}

@Suppress("EXPERIMENTAL_OVERRIDE")
private object DirectUnconfinedDispatcher : CoroutineDispatcher() {
override fun isDispatchNeeded(context: CoroutineContext): Boolean = false
Expand Down
7 changes: 7 additions & 0 deletions retrofit/src/main/java/retrofit2/HttpServiceMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotatio
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
if (getRawType(responseType) == Call.class) {
throw methodError(
method,
"Suspend functions should not return Call, as they already execute asynchronously.\n" +
"Change its return type to %s", Utils.getParameterUpperBound(0, (ParameterizedType) responseType));
}

continuationIsUnit = Utils.isUnit(responseType);
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
Expand Down

0 comments on commit ad84303

Please sign in to comment.