Как я могу поймать исключение в сопрограмме Kotlin, когда я жду его в другой функции? - PullRequest
0 голосов
/ 04 января 2019

Извините за смутное название, не могу придумать что-нибудь получше.

Итак, я прочитал эту статью и хотел сделать то же самое. проблема в том, что я не могу сделать try { promise... } catch (e) { }, потому что ошибка проглатывается. Я могу уловить ошибку там, где я ее жду, но я этого не хочу.

и мой код выглядит так:

typealias Promise<T> = Deferred<T>

fun <T, R> Promise<T>.then(handler: (T) -> R): Promise<R> = GlobalScope.async(Dispatchers.Main) {
    // using try/catch here works but I don't want it here.
    val result = this@then.await()
    handler.invoke(result)
}

object PromiseUtil {
    fun <T> promisify(block: suspend CoroutineScope.() -> T): Promise<T> = GlobalScope.async { block.invoke(this) }
}

// somewhere in my UI testing it.
try {
    PromiseUtil.promisify { throw Exception("some exp") }
        .then { Log.d("SOME_TAG", "Unreachable code.") }
} catch (e: Exception) {
    Log.d("ERROR_TAG", "It should catch the error here but it doesn't.")
}

И я прочитал это и это тоже , но я хочу как-то отлавливать ошибки в коде пользовательского интерфейса и не хочу использовать runBlocking { ... }.

Спасибо.

1 Ответ

0 голосов
/ 04 января 2019

Исключение никогда не перехватывается, потому что оно никогда не передается вызовом async. Это происходит, когда вызывается await().

См. Обработка исключений сопрограммы .

Ваш код должен быть:

// somewhere in my UI testing it.
try {
    PromiseUtil.promisify { throw Exception("some exp") }
        .then { Log.d("SOME_TAG", "Unreachable code.") }.await() // <--- added await() call
} catch (e: Exception) {
    Log.d("ERROR_TAG", "It should catch the error here but it doesn't.")
}

Но это не скомпилируется, так как await() является функцией приостановки. Следовательно, это должно быть больше похоже на:

// somewhere in my UI testing it.
GlobalScope.launch(CoroutineExceptionHandler { coroutineContext, throwable ->
            Log.d("ERROR_TAG", "It will catch error here")
            throwable.printStackTrace()
        }) {
   PromiseUtil.promisify { throw Exception("some exp") }
        .then { Log.d("SOME_TAG", "Unreachable code.") }.await()
}
...