为何子协程的CoroutineExceptionHandler捕获异常而非父SupervisorScope?
问题解答
核心原因:异常处理器的优先级规则
Kotlin协程中,当协程自身上下文携带CoroutineExceptionHandler时,会优先使用自身的处理器捕获并处理异常,不会将异常向上传递给父协程的处理器。你在launch1中显式添加了独立的异常处理器,所以异常直接被它拦截处理,根本不会传到supervisorScope的处理器环节。
关于SupervisorScope的角色
你创建的supervisorScope是带有SupervisorJob的协程作用域,它的核心作用是隔离子协程的异常影响——即某个子协程抛出异常时,不会触发其他同级子协程的取消(比如你的launch2能正常执行就体现了这一点),但它并不改变异常处理的优先级规则。
它确实是launch1和launch2的父协程容器,但这只决定异常的传播范围,不改变“自身处理器优先”的逻辑。
验证:去掉子协程的处理器试试
如果移除launch1的异常处理器,代码修改为:
launch(CoroutineName("launch1")) { throw Exception("[${Thread.currentThread().name}] Error !") }
此时执行结果就会变成supervisorScope的处理器捕获异常:
[DefaultDispatcher-worker-2 @launch2#3] launch2 [DefaultDispatcher-worker-1 - supervisor] Caught java.lang.Exception: [DefaultDispatcher-worker-1 @launch1#2] Error !
补充:父协程处理器生效的场景
只有当子协程上下文**未携带自身的CoroutineExceptionHandler**时,异常才会向上传递,由父协程(或更上层)的处理器处理。如果父协程也没有配置处理器,最终会由全局异常处理器处理(JVM环境下可能导致程序崩溃)。
内容的提问来源于stack exchange,提问作者EARTH H
相关产品推荐
相关产品推荐

