RxJava2中onErrorReturn仅捕获首个异常,如何捕获全部异常?
为什么只捕获到首个异常,以及如何处理多个异常
首先得明确一个RxJava的核心规则:Flowable(以及Observable)的事件流只能有一个终止事件(onError 或 onComplete)。当你调用第一次emitter.onError(new Exception("error1"))时,整个流就已经终止了——订阅者收到这个错误后,就会解除订阅,不再接收后续任何事件。这时候你再调用emitter.onError(new Exception("error2")),这个异常就变成了“无法传递的异常”,也就是你看到的UndeliverableException。
那要处理多个异常,得根据你的实际需求来选方案:
方案1:把多个异常打包成一个复合异常发送
如果这些异常是同一批次的错误,你可以把它们包装成CompositeException,只调用一次onError,这样下游就能一次性处理所有异常:
Flowable.create(emitter -> { List<Throwable> exceptions = new ArrayList<>(); exceptions.add(new Exception("error1")); exceptions.add(new Exception("error2")); // 只发送一次onError,把所有异常打包进去 emitter.onError(new CompositeException(exceptions)); }, BackpressureStrategy.MISSING) .onErrorReturn(e -> { if (e instanceof CompositeException) { // 遍历所有异常并处理 for (Throwable cause : ((CompositeException) e).getExceptions()) { System.out.println("Got error " + cause.getMessage()); } } else { System.out.println("Got error " + e.getMessage()); } return "error"; }) .subscribe();
这个方案的输出会是:
Got error error1 Got error error2
方案2:把异常作为普通事件发送(不终止流)
如果这些异常是需要逐个处理、且不想让流终止的场景,那你不能用onError,而是把异常当作普通的onNext事件发送,下游在map或者doOnNext里处理:
Flowable.create(emitter -> { // 把异常作为普通事件发送,而不是终止事件 emitter.onNext(new Exception("error1")); emitter.onNext(new Exception("error2")); // 最后手动结束流 emitter.onComplete(); }, BackpressureStrategy.MISSING) .map(item -> { if (item instanceof Exception) { System.out.println("Got error " + ((Exception) item).getMessage()); return "error"; } return item.toString(); }) .subscribe();
这种方式下,流不会因为单个异常终止,所有的异常都能被依次处理。
补充:避免UndeliverableException的小技巧
如果你不小心发送了多个onError,可以通过RxJava的全局异常处理器来捕获这些无法传递的异常,避免程序崩溃:
RxJavaPlugins.setErrorHandler(throwable -> { if (throwable instanceof UndeliverableException) { throwable = throwable.getCause(); } // 这里处理无法传递的异常 System.err.println("Undeliverable exception: " + throwable.getMessage()); });
内容的提问来源于stack exchange,提问作者Searene
相关产品推荐
相关产品推荐

