如何让RxJava抛出的真实异常直接传递到非RxJava的Kotlin代码?
我正在使用一个暴露RxJava2 API的库,但我的代码是Kotlin代码且并未使用RxJava。我希望能将RxJava中的异常抛出到外部代码中,以便我的代码可以捕获它。
我想实现类似如下的逻辑:
fun myFun() { someCompletable .doOnError { throw it } .subscribe() }
并且让调用myFun()的用户完全无需了解RxJava。但目前的问题是,RxJava抛出的异常会被包装成OnErrorNotImplementedException,并非我想要的:
io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: [链接已移除] | [原始异常信息]
请问有没有办法让myFun()抛出真实的异常而非OnErrorNotImplementedException?
以下说明为何之前标记的重复问题并不相关:
- 第一个问题「how to return value in RxJava」完全与异常无关。
- 第二个问题「rxjava throws OnErrorNotImplementedException」虽相关,但并非重复:它并未回答我的问题,只是提及了该异常。
你可以通过两种方式实现需求,让原始异常直接抛出,无需RxJava包装:
方式一:使用阻塞式等待方法(针对Completable)
对于Completable类型,直接调用blockingAwait()会同步等待任务完成,若发生异常会直接抛出原始异常,外部代码可以直接捕获:
fun myFun() { someCompletable.blockingAwait() }
这种方式下,调用方完全不需要知道RxJava的存在,和调用普通Kotlin函数捕获异常的逻辑一致。
方式二:显式指定subscribe的错误处理器
如果不想用阻塞方法,也可以在subscribe中传入明确的错误处理逻辑,直接抛出原始异常:
fun myFun() { someCompletable.subscribe( // 任务完成的回调,无需处理可留空 {}, // 错误回调:直接抛出原始异常 { throw it } ) }
这种写法会覆盖RxJava的默认错误处理逻辑,不会再将异常包装成OnErrorNotImplementedException。
为什么之前的写法无效?
你之前用doOnError { throw it }后调用无参数subscribe()时,doOnError只是一个副作用操作,并不会替代subscribe要求的错误处理器。由于没有给subscribe()传入错误处理逻辑,RxJava会触发默认行为,把原始异常包装成OnErrorNotImplementedException抛出。
内容的提问来源于stack exchange,提问作者JonasVautherin

