Retrofit2+RxJava如何获取服务端自定义错误?
如何在Retrofit2+RxJava中获取后端返回的自定义错误体
我太懂这种憋屈的感觉了——明明后端已经返回了定制化的错误信息,结果RxJava的onError里只给了个Throwable,根本摸不到里面的细节。别慌,咱们一步步拆解解决:
第一步:先识别异常类型
Retrofit在遇到非2xx的HTTP状态码时,抛出的异常其实是HttpException,咱们先把Throwable转成这个类型,就能拿到完整的响应对象了:
@Override public void onError(Throwable e) { if (e instanceof HttpException) { HttpException httpException = (HttpException) e; Response<?> response = httpException.response(); // 拿到response后,就可以去解析自定义错误体了 } else { // 处理非HTTP类错误,比如网络断了、解析失败这类 callView(TransactionsFragment::showNetworkError); } }
第二步:解析自定义错误体
接下来把后端返回的errorBody解析成你对应的实体类(比如你示例里的EmailException)。这里用Gson来解析最方便,先确保你有对应的实体类:
@Data public class CustomError { private String message; // 如果后端还有其他字段(比如errorCode),直接加在这里就行 }
然后在刚才的代码里继续处理:
if (response != null && response.errorBody() != null) { try { // 注意:errorBody().string()只能调用一次,因为ResponseBody是流,调用后会关闭 String errorContent = response.errorBody().string(); // 用Gson把字符串转成自定义错误对象 CustomError customError = new Gson().fromJson(errorContent, CustomError.class); // 拿到自定义错误信息,更新UI String errorMsg = customError.getMessage(); callView(view -> view.showCustomError(errorMsg)); } catch (IOException ex) { ex.printStackTrace(); // 解析失败时的兜底处理 callView(TransactionsFragment::showParseError); } } else { // 没有错误体的情况,显示通用错误 callView(TransactionsFragment::showUnknownError); }
第三步:可选——封装成工具类复用
如果多个地方都要处理自定义错误,把解析逻辑抽成工具方法能省不少重复代码:
public class RetrofitErrorParser { public static <T> T parseError(Response<?> response, Class<T> errorClass) { if (response == null || response.errorBody() == null) { return null; } try { String errorBody = response.errorBody().string(); return new Gson().fromJson(errorBody, errorClass); } catch (IOException e) { e.printStackTrace(); return null; } } }
之后在onError里直接调用就行:
CustomError customError = RetrofitErrorParser.parseError(response, CustomError.class); if (customError != null) { callView(view -> view.showCustomError(customError.getMessage())); }
几个要注意的点
- 确保后端返回的
Content-Type是application/json,不然Gson解析会失败 - 别重复调用
errorBody().string(),如果要多次用,先把字符串存起来 - 可以结合
httpException.code()区分不同的HTTP状态码(比如401未授权、404资源不存在),再配合自定义错误信息做更精准的UI提示
内容的提问来源于stack exchange,提问作者ip696
相关产品推荐
相关产品推荐

