suspendCoroutine的异常捕获

suspendCoroutine中可以通过两种方式抛出异常,throw或者resumeWithException

//throw 
suspend fun foo() : String = suspendCoroutine {
    //...
    throw RuntimeException()
}

//resumeWithException
suspend fun foo() : String = suspendCoroutine {
    //...
    resumeWithException(RuntimeException)
}

以上两种情况都可以在外部调用方捕获异常

fun main() {
    runBlocking {
        try { foo() }
        catch ( e: Exception ){
            //ex can be caught here
        }
    }
}

需要特别注意的是Thread中抛出的异常是无法被正常捕获的,因为异常是不能夸线程捕捉的

try {
    thread {
        throw RuntimeException()
    }
} catch (e : Exception) {
    //ex can't caught here
}

所以在resumeWithException中启thread中的异常必须通过resumeWithException抛出

//resumeWithException
suspend fun foo() : String = suspendCoroutine {
    thread {
        try {
            //...
            throw RuntimeException()
        } catch (e: Exception){
            resumeWithException(e)
        }
    }
}

那么在协程里切换线程能?

fun main() {
    runBlocking {
        try {
            withContext(Dispatchers.IO) {
                foo() 
            } 
        } catch ( e: Exception ){
            //ex can be caught here
        }
    }
}

经测试即使切换线程异常也是能被正常捕捉的,所以协程可以帮我们实现跨线程的异常捕捉

你可能感兴趣的:(Kotlin)