一次RxJava2导致的线上崩溃问题:The exception was not handled due to missing onError handler in the subscribe()

本文主要是介绍一次RxJava2导致的线上崩溃问题:The exception was not handled due to missing onError handler in the subscribe(),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

周末正在休(玩)息(LOL),突然产品告诉我线上崩溃率很高,还记得周五测试很忙,没怎么测产品就急着上线了。

吓得我感觉看了下友盟数据,发现错误频次最高的是一个网络请求无法解析域名的异常:

第一反应:国外用户无法解析我们配置后台数据的域名,但是理论上来说也应该是网络错误,而不是闪退呀。

第二反应:看到错误的抛出地址是

io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.void accept(java.lang.Throwable)(Functions.java:704)

是RxJava2里面,仔细看了一下我写的调用代码:

RetrofitManager.service.getConfig(getCommonHead(),map).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).`as`(autoDisposable(AndroidLifecycleScopeProvider.from(this))).subscribe {...}

就是个简单的网络请求配合RxJava2和AutoDispose,看上去莫得问题,因为错误里面有提到“subscribe()”这个方法,查看源码:

注释中明确提到如果被观察者发射了一个error事件,会被封装成一个OnErrorNotImplementedException异常,然后发送给RxJavaPlugins的onError全局处理。

然后我先看了一下subscribe方法的error回调Functions.ON_ERROR_MISSING:

//1
public static final Consumer<Throwable> ON_ERROR_MISSING = new OnErrorMissingConsumer();
//2
static final class OnErrorMissingConsumer implements Consumer<Throwable> {@Overridepublic void accept(Throwable error) {RxJavaPlugins.onError(new OnErrorNotImplementedException(error));}}//3
public OnErrorNotImplementedException(@NonNull Throwable e) {this("The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | " + e, e);}

可以看到里面的错误信息就是我们上面遇到的那个错误,只是这里交给了RxJavaPlugins的onError,而没有直接抛出来。

public static void onError(@NonNull Throwable error) {Consumer<? super Throwable> f = errorHandler;if (error == null) {error = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");} else {if (!isBug(error)) {error = new UndeliverableException(error);}}if (f != null) {try {f.accept(error);return;} catch (Throwable e) {// Exceptions.throwIfFatal(e); TODO decidee.printStackTrace(); // NOPMDuncaught(e);}}error.printStackTrace(); // NOPMDuncaught(error);}

可以看到这个方法里面就是检查了是否为空,然后如果errorHandler不为空,就交给f处理,否则直接通过uncaught()方法抛出异常。

所以问题就在于errorHandler这里,注释里面有相关说明:

大概意思就是说,这个方法是用来接收一些本应该回调到onError但是因为一些原因无法回调的事件,默认会打印异常信息然后抛出异常停止程序,为了避免这种情况,建议我们通过setErrorHandler方法设置一个全局异常处理

 

分析完毕:

     原因就是因为我没实现onError然后有没有全局异常处理器。所以解决方法有两个,1.在调用处加上onError的实现,2.通过RxJavaPlugins.setErrorHandler设置一个全局的回调。第一种方法适合你的异常需要单独处理的情况,第二种适合你的异常处理方式一致或者说不处理的情况。我选择了第二种,一方面是因为我的情况不需要处理,另一方面也是为了避免之后再次因为这个问题闪退。

这篇关于一次RxJava2导致的线上崩溃问题:The exception was not handled due to missing onError handler in the subscribe()的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870455

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件