Skip to content

Commit

Permalink
Make HttpException implement CopyableThrowable + add test
Browse files Browse the repository at this point in the history
  • Loading branch information
frantisek-nagy authored and JakeWharton committed Oct 16, 2020
1 parent 576f23d commit 26638cb
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
16 changes: 14 additions & 2 deletions retrofit/src/main/java/retrofit2/KotlinExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package retrofit2

import kotlinx.coroutines.CopyableThrowable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
Expand Down Expand Up @@ -50,7 +51,7 @@ suspend fun <T : Any> Call<T>.await(): T {
continuation.resume(body)
}
} else {
continuation.resumeWithException(HttpException(response))
continuation.resumeWithException(KotlinHttpException(response))
}
}

Expand All @@ -72,7 +73,7 @@ suspend fun <T : Any> Call<T?>.await(): T? {
if (response.isSuccessful) {
continuation.resume(response.body())
} else {
continuation.resumeWithException(HttpException(response))
continuation.resumeWithException(KotlinHttpException(response))
}
}

Expand Down Expand Up @@ -117,3 +118,14 @@ internal suspend fun Exception.suspendAndThrow(): Nothing {
COROUTINE_SUSPENDED
}
}

private class KotlinHttpException(
private val response: Response<*>
) : HttpException(response), CopyableThrowable<KotlinHttpException> {

override fun createCopy(): KotlinHttpException {
val result = KotlinHttpException(response)
result.initCause(cause)
return result
}
}
56 changes: 56 additions & 0 deletions retrofit/src/test/java/retrofit2/KotlinSuspendTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
Expand All @@ -36,6 +37,9 @@ import retrofit2.helpers.ToStringConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path
import java.io.IOException
import java.io.PrintWriter
import java.io.StringWriter
import java.lang.Runnable
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import kotlin.coroutines.CoroutineContext
Expand Down Expand Up @@ -179,6 +183,58 @@ class KotlinSuspendTest {
}
}

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

server.enqueue(MockResponse().setResponseCode(404))

try {
runBlocking {
val deferred = async { example.body() }

deferred.await()
}
fail()
} catch (e: HttpException) {
val writer = StringWriter()
e.printStackTrace(PrintWriter(writer))
val trace = writer.toString()

assertThat(trace).contains("KotlinSuspendTest")
assertThat(trace).contains("await404")
}
}

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

server.enqueue(MockResponse().setResponseCode(404))

try {
runBlocking {
val job = launch { example.body() }

job.join()
}
fail()
} catch (e: HttpException) {
val writer = StringWriter()
e.printStackTrace(PrintWriter(writer))
val trace = writer.toString()

assertThat(trace).contains("KotlinSuspendTest")
assertThat(trace).contains("launch404")
}
}

@Test fun params() {
val retrofit = Retrofit.Builder()
.baseUrl(server.url("/"))
Expand Down

0 comments on commit 26638cb

Please sign in to comment.