Исключено исключение Kotlin coroutine

Я очень смущен тем, как обработка исключений работает с сопрограммами.

Я надеялся, что можно будет иметь цепочку приостанавливающих функций, которые передавали бы Исключения между собой, как синхронный код. Так что если Reprofit бросил IOException, я мог бы обработать это исключение в начале цепочки приостанавливающих функций, например, в презентаторе, чтобы показать ошибку пользователю.

Я сделал этот простой пример, чтобы опробовать сопроводительные письма, но если я раскомментирую либо throw Exception вызов throw Exception то код после того, как Exception не будет запущен, но Exception не приведет к сбою приложения.

 package com.example.myapplication import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Button import android.widget.TextView import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.launch class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val text = findViewById<TextView>(R.id.thing_text) val button = findViewById<Button>(R.id.thing_button) var count = 0 button.setOnClickListener { launch { count++ // throw Exception("Boom") val string = delayedStringOfInt(count) runOnUiThread { text.text = string } } } } suspend fun delayedStringOfInt(int: Int): String { delay(1000) // throw Exception("Boom") return int.toString() } } 

Я попытался использовать async и CoroutineExceptionHandler .

При использовании async вы должны await результата где-то, чтобы не потерять никаких исключений.

Вот код, который ловит исключение, основанное на ответе Алексея Романова. С немного больше работы у меня есть работа с запуском. Добавление Log.d("thread", Thread.currentThread().name) показывает, что задержки не блокируют пользовательский интерфейс.

 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val text = findViewById<TextView>(R.id.thing_text) val button = findViewById<Button>(R.id.thing_button) var count = 0 button.setOnClickListener { launch { val job = async { count++ val string = delayedStringOfInt(count) updateTextView(text, string) } try { job.await() } catch (e: IOException) { makeToastFromException(e) } } } } fun makeToastFromException(e: Exception) { runOnUiThread { Toast.makeText(this@MainActivity, e.localizedMessage, Toast.LENGTH_SHORT).show() } } fun updateTextView(text: TextView, string: String) { runOnUiThread { text.text = string } } suspend fun delayedStringOfInt(int: Int): String { delay(2000) if (int % 4 == 0) throw IOException("Boom") return int.toString() } }