一次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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu