Kotlin coroutine traga exception

Estoy muy confundido acerca de cómo funciona el event handling excepciones con corutinas.

Esperaba que fuera posible tener una cadena de funciones de suspensión que pasara Excepciones entre ellas como código sincrónico. Entonces, si, por ejemplo, Retrofit lanzó una IOException, podría manejar esa exception al principio de la cadena de funciones de suspensión, como en un presentador, para mostrar un error a un usuario.

Hice este ejemplo simple para probar coroutines pero si elimino el comentario ya sea throw Exception llame al código después de que no se ejecute la exception pero la exception no bloquea la aplicación.

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

He intentado usar async y CoroutineExceptionHandler .

ACTUALIZACIÓN: Basado en la respuesta de Alexey, este código acepta los clics del button de forma asíncrona, pero bloquea el hilo de la interfaz de usuario, que no quiero.

 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 { runBlocking { val job = async { count++ val string = delayedStringOfInt(count) runOnUiThread { text.text = string } } try { job.await() } catch (e: Exception) { Toast.makeText(this@MainActivity, e.localizedMessage, Toast.LENGTH_SHORT).show() } } } } suspend fun delayedStringOfInt(int: Int): String { delay(1000) if (int % 4 == 0) throw Exception("Boom") return int.toString() } }