【发布时间】:2021-05-05 14:35:12
【问题描述】:
我的 Android 应用程序崩溃了,我在 Logcat 中看到了这个堆栈跟踪。它没有告诉我是哪一行代码导致了问题。
2021-05-05 09:13:33.143 1069-1069/com.mycompany.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mycompany.app, PID: 1069
retrofit2.HttpException: HTTP 403
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:53)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:161)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
有没有办法将它映射回我的代码,以查看是哪个改造调用导致了它?我有一个代码如下的存储库:
suspend fun getSomeData(): Stuff {
return withContext(Dispatchers.IO) {
val body = myRetroApi.getStuff()
...
我是否需要包装每个 withContext 主体以确保没有 Throwables 逃逸?我认为如果有什么东西在那里引发了异常,它会记录一个错误,而不是让整个应用程序崩溃。
编辑
我在问这个问题时搞砸了,把重点放在错误的事情上。所以我要删除“改造”标签。事实证明,withContext(Dispatchers.IO) 调用确实按预期重新抛出了Exception,但是当异常返回到viewModelScope.launch 时,如果该块没有捕获它,应用程序就会崩溃。
【问题讨论】:
-
I thought that if something threw an exception there, it would log an error, not crash the entire app.这是一个大胆的假设:) -
是的,我想是的,尽管它基于服务器端 Java 和后台线程的类似经验。让我吃惊的不是崩溃;更重要的是堆栈跟踪没有指向我的代码中的任何内容。
-
对于协程,你需要提供自己的错误处理,如果你只是做一些研究,你可以找到很多这方面,人们通常使用
safeApiCall包装器来执行协程调用并返回结果 -
好的,谢谢。堆栈跟踪根本不指向您的代码是否正常?我不习惯,但也许这是协程的标准?
-
协程异常处理非常复杂,很难记住所有关于其行为的奇怪规则。我的建议是在可能的最低点捕获可能的异常,并使用结果包装密封类来包装它们,这是 Java 已检查异常的 Kotlin 替代方案。
标签: android kotlin kotlin-coroutines