UndeclaredThrowableException when using "suspend" modifier
See original GitHub issueRetrofit crashes with UndeclaredThrowableException when using suspend modifier and making multiple requests which are supposed to throw IOException.
Retrofit version: 2.6.0, 2.6.1-SNAPSHOT (20190612)
class RetrofitUndeclaredThrowableExceptionBug {
interface Service {
@GET("/")
suspend fun download()
}
@Test
fun test() = runBlocking {
val retrofit = Retrofit.Builder()
.baseUrl("https://unresolved-host.com/") // An unresolved host to simulate IOException
.build()
val service = retrofit.create<Service>(Service::class.java)
// First attempt works fine
try {
service.download()
} catch (e: IOException) {
println("Catched 1: $e")
}
// Second attempt sometimes crashes
try {
service.download()
} catch (e: IOException) {
println("Catched 2: $e")
}
// And this will crash for sure (sometimes sooner, sometimes later)
repeat(Integer.MAX_VALUE) {
try {
service.download()
} catch (e: IOException) {
println("Catched 3: $e")
}
}
}
}
Issue Analytics
- State:
- Created 4 years ago
- Reactions:9
- Comments:16 (10 by maintainers)
Top Results From Across the Web
Exceptions and proxies and coroutines, oh my! - Jake Wharton
Retrofit uses the suspendCoroutine API with its own Callback to suspend while the HTTP request is sent on a background thread. suspend fun...
Read more >When Does Java Throw UndeclaredThrowableException?
Theoretically speaking, Java will throw an instance of UndeclaredThrowableException when we try to throw an undeclared checked exception.
Read more >Kotlin suspend modifier changes function signature, but ...
The following code does not compile, because two functions with the same signature are conflicting. conflicting overloads: public fun foo(x: Int): ...
Read more >Thread - Android Developers
This method exists solely for use with suspend() , which has been deprecated because it is deadlock-prone. For more information, see Why are...
Read more >UndeclaredThrowableException (Java Platform SE 8 )
An UndeclaredThrowableException instance contains the undeclared checked exception that was thrown by the invocation handler, and it can be retrieved with ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

The same happens when throwing an exception from an interceptor
There should be a fat warning on the release notes, that using
suspendmodifier for retrofit is not production ready.Network calls can throw checked
IOExceptions so you need to declare@Throws(IOException::class)on every single function on your interface or it will blow up at runtime.