当前位置: 首页 > 知识库问答 >
问题:

Android coroutines处理异常

仲阳朔
2023-03-14

在我的应用程序里。我正试图使用Kotlin Coroutines发送网络请求。我分析了一些情况下的响应和抛出异常。下面是代码

class ProxyErrorInterceptor : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val response = chain.proceed(request)
        val bodyString = response.body()?.string()
        when (response.code()) {
            HttpURLConnection.HTTP_OK -> {
                val error = Gson().fromJson(bodyString, BusinessModel::class.java)
                if (error.errorCode != null) {
                    throw BusinessDataException(error.errorCode, error.errorMessage)
                }
            }
            HttpURLConnection.HTTP_INTERNAL_ERROR -> {
                val error = Gson().fromJson(bodyString, BusinessModel::class.java)
                if (error.errorCode != null) {
                    throw BusinessDataException(error.errorCode, error.errorMessage)
                }
            }
        }
        return response.newBuilder()
                .body(ResponseBody.create(response.body()?.contentType(), bodyString)).build()
    }
}

此拦截异常。

fun getAccounts() {
    try {
        val myJob = GlobalScope.launch(Dispatchers.IO) {
            val response = interactor.getAccounts()
            launch(Dispatchers.Default) {
                data.postValue(mapper.mapAccountList(response))
            }
        }
    } catch (e: Exception) {
        Log.d("Проверка", e.message)
    }
}
fun getAccounts() {
    val myJob = GlobalScope.launch(handler) {
        val response = interactor.getAccounts()
        launch(Dispatchers.Default) {
            loadingStatus.progress.set(false)
            data.postValue(mapper.mapAccountList(response))
        }
    }
}

private val handler = CoroutineExceptionHandler { _, exception ->
    error.postValue(Any())
    loadingStatus.progress.set(false)
    when (exception) {
        is BusinessDataException -> {
            Log.d("Check", exception.message)
        }
        else -> {
            loadingStatus.hasError.set(true)
            loadingStatus.textError.set(exception.message)
        }
    }
}

logcat中的此异常消息

06-03 17:18:01.012 237 96-24010/ru.mtsbank.dbosme e/androidruntime:致命异常:OkHttp调度程序流程:ru.mtsbank.dbosme,pid:23796 java.lang.错误:ru.mtsbank.dbosme.exceptions.businessDataException:www.cantsbank.dbosme.在java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1119)在java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:588)在java.lang.thread.run(threadpoolexecutor.java:818)由:ru.mtsbank.dbosme.exceptions.businessdataexception:businessdataexception:businessdataexception在ru.mtsbank.dbosme.data.web.interceptors.proxyerrorinceptor.incept(proxyerrorinceptor.kt:27)在OKHTTP3.internal.http.realinceptorchain.proce(realinceptorchain.java:147)在OKHTTP3.internal.http.realinceptorchain.proce(realinceptorchain.java:121)在ain.java:121)在OKHTTP3.logging.HttpLoggingInterceptor.Interceptor.java:211)在OKHTTP3.internal.http.realInterceptorchain.proce(realInterceptorchain.java:147)在OKHTTP3.internal.http.realInterceptorchain.proce(realInterceptorchain.java:121)在OKHTTP3.internal.http.realInterceptorchain.java:121)在在java.util.concurrent.ThreadPoolExecutor$worker.run(ThreadPoolExecutor.java:588)处的ent.threadPoolExecutor.runworker(threadPoolExecutor.java:1113) 在java.lang.thread.run(thread.java:818) 

共有1个答案

司英彦
2023-03-14

我认为loadingstatus.progress.set(false)是问题所在。它不会在主线程中执行,这可能会引发异常。每当更新UI时,请使用dispatchers.main而不是dispatchers.default

 类似资料:
  • 我对Spring批处理跳过逻辑有一些问题。我已经配置了一个作业的步骤来跳过两个异常(SQLIntegrityConstraintViolation异常和乐观锁定失败异常): 但当作业运行时,由于我将其配置为跳过的异常,作业以未知状态完成: 我做错什么了吗?我希望这一步跳过负责抛出其中一个异常的项,并继续处理,以便以完成状态结束。

  • 我不知道该怎么办。 当我试图从解析器获取语法错误的数量时,它显示0。 编辑: 它返回null。

  • Blade 内置了 异常处理器,在开发者模式下它会将异常输出在前端页面,并在控制台打印堆栈信息,生产环境只打印在控制台。 有些时候不满足我们的需求,这时候就需要自定义异常处理了,比如针对某个自定义的异常进行特殊处理。 我们用一个例子来解释如何操作。 定义了一个名为 TipException 的运行时异常类,用于输出错误消息到前台。 按照上面对异常的处理情况这个异常的堆栈信息会被输出在控制台,生产环

  • 任何方法都可以抛出不同类型的异常。这些异常可能是需要应用程序重新部署来解决的编程错误,或者是不需要重新部署但可以解决的暂时性错误。 Hangfire可以处理所有内部的(属于Hangfire本身)和相关的外部方法(任务,过滤器等)的异常,因此不会导致整个应用程序被关闭。所有内部异常都被记录(所以不要忘记 启用日志),最糟糕的情况是导致后台任务被暂停并延时重试 10 次。 当Hangfire遇到在执行

  • 我们在编写程序的时候,经常需要对异常情况做处理。比如,当一个数试图除以 0 时,我们需要捕获这个异常情况并做处理。你可能会使用类似 if/else 的条件语句来对异常情况做判断,比如,判断除法的分母是否为零,如果为零,则打印错误信息。 这在某些简单的情况下是可以的,但是,在大多数时候,我们应该使用 Python 的异常处理机制。这主要有两方面的好处: 一方面,你可以选择忽略某些不重要的异常事件,或

  • 异常处理可以使程序在流程上更加完善。 在 JavaScript 中可以使用 throw 抛出异常,使用 try ... catch 捕获错误。 1. throw throw 语句用来抛出一个用户自定义的异常。(MDN) throw 用于抛出一个异常,这种异常通常是程序出现了不符合预期的错误。 alert('出错前'); throw '发生了一个错误!'; alert('出错后'); 当出现

  •  异常是指正常情况下不会发生的所谓「例外」的情况。在大部分情况下异常和错误可以当作同义词。 异常会发生的地方  程序的任何地方都有发生异常的可能性。  发生异常的时候,异常将被「投出(throw)」。  比如说,以下的脚本将会引起错误。 例: "3%0"!;//发生“除以0错误”的异常  虽然有像上例一样明显会发生异常的情况,但也有一些情况下,无法知道代码是否一定会发生异常。 异常的捕捉  使用

  • 在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处理的异常的话,都会导致对应的 Worker 进程 被中断退出,这对服务而言也是不能接受的,捕获异常并输出合理的报错内容给客户端也是更加友好的。 我们可以通过对各个 server 定义不同的 异常处理器(ExceptionHandler),一旦业务流程存在没有捕获的异常,都会被传递到已注册的