kotlin: 异常捕捉不到的情况

一,CoroutineExceptionHandler捕获异常的条件

CoroutineExceptionHandler 捕获异常需要两个条件:

  • 这个异常是自动传播的。
  • CoroutineExceptionHandler 位于 CoroutineScope 的 CoroutineContext 中,
    或 supervisorScope 的直接子协程中,或其他根协程中。

这样的设计是合理的,
因为 CoroutineScope 的子协程不应该捕获异常,CoroutineScope 的设定就是子协程的异常交由父类处理,
所以应该在 CoroutineScope 创建的根协程中捕获此异常。
而 supervisorScope 的设定是子协程的异常自己处理,所以 supervisorScope 的子协程可以自己捕获异常。

二,例子:捕捉不到异常

 原因:  handler 放在了 scope 子协程的子协程中,
          这时异常会往父协程抛出,不会被自己捕获

代码:

        //处理按钮点击事件
        binding.button1.setOnClickListener {
            runBlocking {

                val handler = CoroutineExceptionHandler { _, e ->
                    println("捕捉到了异常: $e")
                }
                val scope = CoroutineScope(Job())
                val job = scope.launch {
                    launch(handler) {
                        println("将要抛出异常")
                        throw Exception("发生了异常")
                    }
                }
                job.join()

            }
        }

运行结果:

image

三,例子,把handler放到父协程中,使可以捕捉到异常

代码:

        //处理按钮点击事件
        binding.button2.setOnClickListener {
            runBlocking {
                val handler = CoroutineExceptionHandler { _, e ->
                    println("捕捉到了异常: $e")
                }
                val scope = CoroutineScope(Job())
                val job = scope.launch(handler) {
                    launch {
                        println("将要抛出异常")
                        throw Exception("发生了异常")
                    }
                }
                job.join()
            }
        }

参数也可以放到scope中,如下

        //处理按钮点击事件
        binding.button2.setOnClickListener {
            runBlocking {
                val handler = CoroutineExceptionHandler { _, e ->
                    println("捕捉到了异常: $e")
                }
                val scope = CoroutineScope(Job()+handler)
                val job = scope.launch {
                    launch {
                        println("将要抛出异常")
                        throw Exception("发生了异常")
                    }
                }
                job.join()
            }
        }

运行结果:

image

 

posted @ 2025-08-09 13:41  刘宏缔的架构森林  阅读(23)  评论(0)    收藏  举报