Retrofit2的onFailure回调分类捕获异常实现对应错误提示
Retrofit2 onFailure 异常分类处理实现
Retrofit的onFailure回调抛出的Throwable会经过OkHttp、业务逻辑层多层包装,直接调用getMessage()经常返回null,需要按异常类型逐层判断分类,具体实现如下:
完整实现代码
@Override public void onFailure(Throwable t) { // 如果项目有自定义异常包装逻辑,先拆出原始异常 while (t.getCause() != null && t instanceof RuntimeException) { t = t.getCause(); } String errorMsg; if (t instanceof IOException) { // 网络IO类异常,细分网络状态、超时场景 if (!isNetworkAvailable()) { errorMsg = "无网络连接,请检查网络设置"; } else if (t instanceof SocketTimeoutException || t instanceof ConnectTimeoutException) { errorMsg = "请求超时,请稍后重试"; } else if (t instanceof UnknownHostException) { // 域名解析失败通常对应网络断开、DNS不可用场景 errorMsg = "无网络连接,请检查网络设置"; } else { errorMsg = "网络连接异常,请稍后重试"; } } else if (t instanceof HttpException) { // 请求已到达服务端,返回非2xx/3xx的HTTP错误状态码 HttpException httpException = (HttpException) t; int errorCode = httpException.code(); if (errorCode == 401) { errorMsg = "凭证无效,请重新登录"; } else if (errorCode >= 500) { errorMsg = "服务器内部错误,请稍后重试"; } else { errorMsg = "请求异常,请稍后重试"; } } else { // 数据解析异常、未知运行时异常等归为内部错误 errorMsg = "应用内部错误,请稍后重试"; } Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_SHORT).show(); } /** * 判断当前设备网络是否可用 * 需要在AndroidManifest中声明ACCESS_NETWORK_STATE权限 */ private boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) return false; NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnected(); }
注意事项
- 需要在
AndroidManifest.xml中声明网络状态权限,该权限属于普通权限,Android 6.0+不需要动态申请:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 如果你的后端用其他状态码标识凭证失效(比如403、自定义业务码),直接调整
HttpException分支下的状态码判断逻辑即可。 - 如果需要细分服务器错误类型(比如502网关错误、503服务不可用),可以在5xx状态码的判断分支下继续拆分对应提示。
- 数据解析失败抛出的
JsonSyntaxException、自定义拦截器抛出的非IO异常都会走到内部错误分支,符合分类要求。
内容的提问来源于stack exchange,提问作者Husky
相关产品推荐
相关产品推荐

