抛出自定义异常替代其他异常时出现未处理IOException如何解决?
问题原因
- OkHttp的
execute()方法默认声明抛出受检异常IOException,网络请求失败、连接超时等场景都会触发该异常,必须显式处理 - 原有代码通过
catch (Exception e)吞掉了所有异常,移除catch后受检异常未处理就会编译报错 - 补充:原有代码的catch块中直接引用
response存在空指针风险,如果execute()执行失败,response变量未完成初始化,调用Util.getErrorMsg(response)会直接触发NPE
解决步骤
你需要的4种自定义异常可对应如下场景:FirstCustomException(对应500响应码)、SecondCustomException(对应404响应码)、RequestFailCustomException(对应请求执行阶段IO异常)、UnknownCustomException(对应其他响应码)。
1. 完善Util类的handleResponse方法
public void handleResponse(Response<DataGeneralResponse> response) throws CustomException { // 提前判空避免空指针 if (response == null) { throw new UnknownCustomException("响应为空"); } String errorMsg = Util.getErrorMsg(response); switch (response.code()) { case 500: throw new FirstCustomException("服务端内部错误:" + errorMsg); case 404: throw new SecondCustomException("请求资源不存在:" + errorMsg); default: throw new UnknownCustomException("未知响应错误,错误码:" + response.code() + ",错误信息:" + errorMsg); } }
2. 调整getData方法的异常处理逻辑
保留try-catch结构,仅捕获IOException转成第四种自定义异常抛出,不再吞所有异常:
public List<Map<String, Object>> getData(String product) throws CustomException { Response<DataGeneralResponse> response = null; try { response = dataApi.dataGet(product).execute(); if (!response.isSuccessful()) { log.error("Failed to get data for product [{}] error [{}]", product, Util.getErrorMsg(response)); Util.handleResponse(response); } DataGeneralResponse body = response.body(); return body != null ? body.getData(): null; } catch (IOException e) { // IO异常转第四种自定义异常抛出 log.error("Failed to get data for product [{}] error: {}", product, e.getMessage(), e); throw new RequestFailCustomException("请求执行失败:" + e.getMessage(), e); } }
补充说明
- 所有自定义异常建议统一继承父异常
CustomException,方法上只需要声明抛出CustomException即可,上层调用方可以统一捕获父类处理,也可以按需捕获子类做差异化逻辑 - 如果不希望上层调用方处理受检异常,可以把
CustomException定义为继承RuntimeException,这样方法上不需要显式声明throws,也不会有编译报错
内容的提问来源于stack exchange,提问作者mathkid
相关产品推荐
相关产品推荐

