user1854307
user1854307

Reputation: 624

Android coroutines handle exception

In my app. I am trying to send network request using Kotlin Coroutines. I analyzed response and throw exception for some situation.This is the code:

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()
    }
}

This intercept exception.

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)
    }
}

However this didn't worked out and Finally my app crashed.

UPDATE

I tried use CoroutineExceptionHandler but it not helped

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)
        }
    }
}

UPDATE 2

This exception message in logcat

06-03 17:18:01.012 23796-24010/ru.mtsbank.dbosme E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher Process: ru.mtsbank.dbosme, PID: 23796 java.lang.Error: ru.mtsbank.dbosme.exceptions.BusinessDataException: Нарушен контракт взаимодействия, и дальше описание, что не так... at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1119) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by: ru.mtsbank.dbosme.exceptions.BusinessDataException: Нарушен контракт взаимодействия, и дальше описание, что не так... at ru.mtsbank.dbosme.data.web.interceptors.ProxyErrorInterceptor.intercept(ProxyErrorInterceptor.kt:27) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) at ru.mtsbank.dbosme.data.web.interceptors.MainInterceptor.intercept(MainInterceptor.kt:18) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:211) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200) at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147) at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  at java.lang.Thread.run(Thread.java:818) 

Upvotes: 0

Views: 1100

Answers (1)

apksherlock
apksherlock

Reputation: 8371

I believe loadingStatus.progress.set(false) is the problem. That's not getting executed in the Main Thread which might throw an exception. Whenever you are updating the UI go with Dispatchers.MAIN instead of Dispatchers.Default

Upvotes: 0

Related Questions