Skip to content

Commit 26638cb

Browse files
frantisek-nagyJakeWharton
authored andcommitted
Make HttpException implement CopyableThrowable + add test
1 parent 576f23d commit 26638cb

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

retrofit/src/main/java/retrofit2/KotlinExtensions.kt

+14-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package retrofit2
2020

21+
import kotlinx.coroutines.CopyableThrowable
2122
import kotlinx.coroutines.Dispatchers
2223
import kotlinx.coroutines.suspendCancellableCoroutine
2324
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
@@ -50,7 +51,7 @@ suspend fun <T : Any> Call<T>.await(): T {
5051
continuation.resume(body)
5152
}
5253
} else {
53-
continuation.resumeWithException(HttpException(response))
54+
continuation.resumeWithException(KotlinHttpException(response))
5455
}
5556
}
5657

@@ -72,7 +73,7 @@ suspend fun <T : Any> Call<T?>.await(): T? {
7273
if (response.isSuccessful) {
7374
continuation.resume(response.body())
7475
} else {
75-
continuation.resumeWithException(HttpException(response))
76+
continuation.resumeWithException(KotlinHttpException(response))
7677
}
7778
}
7879

@@ -117,3 +118,14 @@ internal suspend fun Exception.suspendAndThrow(): Nothing {
117118
COROUTINE_SUSPENDED
118119
}
119120
}
121+
122+
private class KotlinHttpException(
123+
private val response: Response<*>
124+
) : HttpException(response), CopyableThrowable<KotlinHttpException> {
125+
126+
override fun createCopy(): KotlinHttpException {
127+
val result = KotlinHttpException(response)
128+
result.initCause(cause)
129+
return result
130+
}
131+
}

retrofit/src/test/java/retrofit2/KotlinSuspendTest.kt

+56
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import kotlinx.coroutines.CoroutineDispatcher
1919
import kotlinx.coroutines.ExperimentalCoroutinesApi
2020
import kotlinx.coroutines.GlobalScope
2121
import kotlinx.coroutines.async
22+
import kotlinx.coroutines.launch
2223
import kotlinx.coroutines.runBlocking
2324
import kotlinx.coroutines.withContext
2425
import okhttp3.OkHttpClient
@@ -36,6 +37,9 @@ import retrofit2.helpers.ToStringConverterFactory
3637
import retrofit2.http.GET
3738
import retrofit2.http.Path
3839
import java.io.IOException
40+
import java.io.PrintWriter
41+
import java.io.StringWriter
42+
import java.lang.Runnable
3943
import java.lang.reflect.ParameterizedType
4044
import java.lang.reflect.Type
4145
import kotlin.coroutines.CoroutineContext
@@ -179,6 +183,58 @@ class KotlinSuspendTest {
179183
}
180184
}
181185

186+
@Test fun await404() {
187+
val retrofit = Retrofit.Builder()
188+
.baseUrl(server.url("/"))
189+
.addConverterFactory(ToStringConverterFactory())
190+
.build()
191+
val example = retrofit.create(Service::class.java)
192+
193+
server.enqueue(MockResponse().setResponseCode(404))
194+
195+
try {
196+
runBlocking {
197+
val deferred = async { example.body() }
198+
199+
deferred.await()
200+
}
201+
fail()
202+
} catch (e: HttpException) {
203+
val writer = StringWriter()
204+
e.printStackTrace(PrintWriter(writer))
205+
val trace = writer.toString()
206+
207+
assertThat(trace).contains("KotlinSuspendTest")
208+
assertThat(trace).contains("await404")
209+
}
210+
}
211+
212+
@Test fun launch404() {
213+
val retrofit = Retrofit.Builder()
214+
.baseUrl(server.url("/"))
215+
.addConverterFactory(ToStringConverterFactory())
216+
.build()
217+
val example = retrofit.create(Service::class.java)
218+
219+
server.enqueue(MockResponse().setResponseCode(404))
220+
221+
try {
222+
runBlocking {
223+
val job = launch { example.body() }
224+
225+
job.join()
226+
}
227+
fail()
228+
} catch (e: HttpException) {
229+
val writer = StringWriter()
230+
e.printStackTrace(PrintWriter(writer))
231+
val trace = writer.toString()
232+
233+
assertThat(trace).contains("KotlinSuspendTest")
234+
assertThat(trace).contains("launch404")
235+
}
236+
}
237+
182238
@Test fun params() {
183239
val retrofit = Retrofit.Builder()
184240
.baseUrl(server.url("/"))

0 commit comments

Comments
 (0)