Kotlin协程invokeOnCompletionHandler的cause为空矛盾问题排查
问题分析与解决方案
核心问题
你混淆了invokeOnCompletion参数it的含义:it本身就是协程的失败原因(抛出的异常),而非一个包含cause的包装对象。你调试器中看到的it不为空但it.cause为空,正是因为it就是抛出的根异常本身——它没有嵌套的cause,所以it?.cause == null的判断结果为true,错误触发了导航代码。
同时,CoroutineExceptionHandler的作用是捕获并处理未被协程内部捕获的异常,但它不会改变协程的失败状态:协程仍然会以失败告终,invokeOnCompletion依然会收到这个异常作为参数。
修复代码
将判断逻辑从it?.cause == null改为it == null,仅当协程正常完成(无异常)时才执行导航:
lifecycleScope.launch(CoroutineExceptionHandler { _, e -> println(e) // 正常输出异常信息 }) { val user = viewModel.findById(userId) // 抛出异常 }.invokeOnCompletion { if (it == null) // 仅当协程正常完成时执行导航 findNavController().navigate(R.id.action_userForm_to_userList) }
额外说明
根据官方文档:
当Job正常完成时,Cause为空。
这里的“Cause”指的就是invokeOnCompletion的参数it,而非it?.cause。当协程失败时,it为抛出的异常实例;正常完成时,it为null。
内容的提问来源于stack exchange,提问作者Source
相关产品推荐
相关产品推荐

