Retrofit调用错误控制:获取Http响应码并统一处理错误
统一Retrofit网络错误处理实现方案
针对你想要获取Http响应码并统一处理所有类型错误的需求,我整理了一套实用的实现方案,既能封装不同类型的网络错误,又能方便地在UI层展示给用户。
1. 先创建统一错误处理工具类
我们可以写一个NetworkErrorHandler类,专门负责解析各种Throwable异常,把错误码和错误信息封装成统一的模型,这样所有请求的错误处理逻辑都能复用:
public class NetworkErrorHandler { // 解析异常,返回封装好的错误模型 public static ErrorModel handleError(Throwable e) { ErrorModel errorModel = new ErrorModel(); if (e instanceof HttpException) { // 处理Http异常,提取响应码 HttpException httpException = (HttpException) e; errorModel.setErrorCode(httpException.code()); // 根据常见Http码设置对应提示 switch (httpException.code()) { case 400: errorModel.setErrorMessage("请求参数有误,请检查后重试"); break; case 401: errorModel.setErrorMessage("登录已过期,请重新登录"); break; case 403: errorModel.setErrorMessage("暂无权限访问该资源"); break; case 404: errorModel.setErrorMessage("请求的资源不存在"); break; case 500: errorModel.setErrorMessage("服务器繁忙,请稍后再试"); break; default: errorModel.setErrorMessage("网络请求失败,错误码:" + httpException.code()); break; } } else if (e instanceof IOException) { // 处理网络连接类错误,比如断网 errorModel.setErrorCode(-1); errorModel.setErrorMessage("网络连接失败,请检查你的网络设置"); } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) { // 处理数据解析错误 errorModel.setErrorCode(-2); errorModel.setErrorMessage("数据解析失败,请稍后重试"); } else { // 其他未知错误 errorModel.setErrorCode(-3); errorModel.setErrorMessage("未知错误:" + e.getMessage()); } return errorModel; } // 封装错误信息的实体类 public static class ErrorModel { private int errorCode; private String errorMessage; public int getErrorCode() { return errorCode; } public void setErrorCode(int errorCode) { this.errorCode = errorCode; } public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } } }
2. 改造现有Observer,接入统一错误处理
接下来把你原来的getObserver()方法里的错误处理逻辑替换成调用这个工具类,这样就能统一处理所有错误了:
public Observer<Response> getObserver(){ Observer<Response> response = new Observer<Response>() { @Override public void onSubscribe(Disposable d) { Log.d("test", "onSubscribe"); } @Override public void onNext(Response response) { Log.d("test", "onNext"); fragmentInterface.showMovies(response); } @Override public void onError(Throwable e) { Log.d("test", "onError"); e.printStackTrace(); // 用统一工具类解析错误 NetworkErrorHandler.ErrorModel errorModel = NetworkErrorHandler.handleError(e); // 把错误信息展示给用户,这里通过你的fragmentInterface回调 fragmentInterface.showError(errorModel.getErrorMessage()); // 如果需要针对特定错误码做逻辑处理,比如401跳转登录 if (errorModel.getErrorCode() == 401) { // 这里可以添加跳转到登录页的逻辑 // Intent loginIntent = new Intent(getContext(), LoginActivity.class); // startActivity(loginIntent); } } @Override public void onComplete() { Log.d("test", "onComplete"); } }; return response; }
3. 进阶优化:封装BaseObserver减少重复代码
如果你的项目中有很多网络请求,每个都写一遍Observer的模板代码太麻烦,我们可以封装一个BaseObserver抽象类,把通用的订阅、错误、完成逻辑都封装进去,子类只需要实现成功和错误的回调即可:
public abstract class BaseObserver<T> implements Observer<T> { @Override public void onSubscribe(Disposable d) { // 通用订阅逻辑,比如可以把Disposable加入CompositeDisposable统一管理 Log.d("test", "onSubscribe"); } @Override public void onError(Throwable e) { Log.d("test", "onError"); e.printStackTrace(); NetworkErrorHandler.ErrorModel errorModel = NetworkErrorHandler.handleError(e); // 回调给子类处理错误 onErrorReceived(errorModel); } @Override public void onComplete() { Log.d("test", "onComplete"); } // 子类实现:处理成功响应 public abstract void onNext(T t); // 子类实现:处理错误信息 public abstract void onErrorReceived(NetworkErrorHandler.ErrorModel errorModel); }
之后使用的时候就变得非常简洁:
public Observer<Response> getObserver(){ return new BaseObserver<Response>() { @Override public void onNext(Response response) { Log.d("test", "onNext"); fragmentInterface.showMovies(response); } @Override public void onErrorReceived(NetworkErrorHandler.ErrorModel errorModel) { fragmentInterface.showError(errorModel.getErrorMessage()); // 处理特定错误码逻辑 if (errorModel.getErrorCode() == 401) { // 执行登录跳转等操作 } } }; }
这样一来,所有网络请求的错误处理都统一了,不管是Http响应码错误、网络断开还是数据解析失败,都能给用户展示清晰的提示,同时也方便后续扩展新的错误类型。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

