You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:49:16