question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

UndeclaredThrowableException when using "suspend" modifier

See original GitHub issue

Retrofit 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:closed
  • Created 4 years ago
  • Reactions:9
  • Comments:16 (10 by maintainers)

github_iconTop GitHub Comments

5reactions
PaulWoitaschekcommented, Jun 28, 2019

The same happens when throwing an exception from an interceptor

3reactions
PaulWoitaschekcommented, Jul 1, 2019

There should be a fat warning on the release notes, that using suspend modifier 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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found