When using suspending async/await, stacktrace contains no application code
See original GitHub issueCan be reproduced by simple test:
@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("KotlinSuspendTest" in trace).isTrue()
assertThat("await404" in trace).isTrue()
}
}
By default the stacktrace will look like:
retrofit2.HttpException: HTTP 404 Client Error
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:53)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:161)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
This is not very helpful, as we don’t know which call caused the exception.
Attempt at fixing can be found in https://github.com/square/retrofit/pull/3475, comments appreciated. That would lead to following trace:
retrofit2.HttpException: HTTP 404 Client Error
(Coroutine boundary)
at retrofit2.KotlinSuspendTest$await404$1$deferred$1.invokeSuspend(KotlinSuspendTest.kt:190)
Caused by: retrofit2.HttpException: HTTP 404 Client Error
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:53)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:161)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Issue Analytics
- State:
- Created 3 years ago
- Reactions:15
- Comments:7 (1 by maintainers)
Top Results From Across the Web
Asynchronous stack traces: why await beats Promise#then()
With await , we can restore the call chain even if we do not collect the stack trace at the await call. This...
Read more >can I stop a task in C# and get a stack trace
I've got a base level function in xunit looks sort of like: async Task LimitTestTo( Timespan maxTime, Task theTest ) { await Task....
Read more >Async await hangs in ASP.NET Core, MVC and WebAPI
Debugging async await hangs is hard! When I first wrote the LeanSentry Hang diagnostics, most .NET web applications were developed using ...
Read more >Diagnose async hangs in ASP.NET Core, MVC and WebAPI
NET Core, MVC and WebAPI applications, using the async analysis inside ... tasks have no readily apparent “stacks” showing where the code is...
Read more >Connecting async/await to other Swift code
Particularly, the newly introduced async/await pattern could not ... asynchronous code on Apple's platforms going forward, like with all ...
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

Yes @Red7M , you can surround all calls to retrofit in try/catch blocks. And then you invoke wrapToBeTraceable() to get the real stack trace: Like
its ugly but the only way I can see to get at least some useful information.
I have added wrong headers that caused me that HTTP 400 Bad request error.
removing the following worked .addHeader(“Content-Encoding”, “UTF-8”) .header(“Accept-Encoding”, “identity”)