你当前的代码中使用了 try...catch (Exception e) 来捕获所有异常,这种方式虽然能“兜底”,但 无法区分具体的异常类型,比如:
是网络超时?
是空指针?
是 JSON 解析失败?
是数据库异常?
✅ 你的需求:
在 pushOrderInfo 方法中,如何在 try...catch 中单独识别出三方请求超时的情况?
🧠 原理说明
三方请求超时通常是由 HTTP 客户端抛出的异常 引发的,例如:
HTTP客户端 超时异常类
Apache HttpClient java.net.SocketTimeoutException 或 org.apache.http.conn.ConnectTimeoutException
OkHttp java.net.SocketTimeoutException
Spring RestTemplate 同上,取决于底层实现
自定义封装(如你用的 HttpClientUtil.sendPostByJson) 可能是包装后的异常
所以你要做的是:
✅ 在 catch 块中判断是否是超时相关的异常。
✅ 示例改进:区分超时和其他异常
Java
深色版本
public BaseResp<CreditOrderApplyResp> pushOrderInfo(ApplyReq bizReq) {
try {
} catch (SocketTimeoutException e) {
// 捕获到请求超时
log.error("请求机构{}发生三方请求超时", bizReq.getInstitutionCode(), e);
return BaseResp.fail(ErrorCodeEnum.THIRD_PARTY_TIMEOUT); // 返回自定义超时错误码
} catch (ConnectTimeoutException e) {
// 连接超时(可选)
log.error("请求机构{}发生连接超时", bizReq.getInstitutionCode(), e);
return BaseResp.fail(ErrorCodeEnum.CONNECTION_TIMEOUT);
} catch (Exception e) {
// 兜底其他异常
log.error("请求机构{}获取进件接口数据异常", bizReq.getInstitutionCode(), e);
return BaseResp.fail(ErrorCodeEnum.ERROR);
}
return BaseResp.success(bizResp);
}
🔍 关键点解释
1. SocketTimeoutException
表示读取超时(即调用第三方接口后,对方没有及时返回响应),是最常见的三方超时异常。
2. ConnectTimeoutException
来自 Apache HttpClient,表示建立连接阶段就超时了(比如对方服务器不可达、DNS解析慢等)。
如果你不确定用了哪种 HTTP 客户端,可以只捕捉 SocketTimeoutException。
✅ 如何确认实际抛出的异常类型?
你可以通过以下方式确认你项目中实际会抛出什么类型的异常:
方法一:调试或日志打印
在 catch 块中加入如下代码:
Java
深色版本
} catch (Exception e) {
log.error("异常类型: {}", e.getClass().getName());
log.error("异常信息:", e);
}
然后看日志输出就知道具体是哪一种异常了。
✅ 建议:定义一个统一的超时处理方法(可选)
如果你多个地方都需要处理三方超时,可以抽象一个工具方法:
Java
深色版本
public boolean isTimeoutException(Throwable t) {
return t instanceof SocketTimeoutException ||
t instanceof ConnectTimeoutException;
}
然后在 catch 中调用它:
Java
深色版本
if (isTimeoutException(e)) {
return BaseResp.fail(ErrorCodeEnum.THIRD_PARTY_TIMEOUT);
}
✅ 最佳实践总结
场景 推荐做法
区分超时和其他异常 单独 catch SocketTimeoutException
不确定异常类型 打印 e.getClass() 查看真实类型
多个方法需要超时处理 提取成工具方法复用
日志记录 记录机构编码和异常堆栈,方便排查问题
如果你能提供你使用的 HTTP 工具类(如 HttpClientUtil 的实现),我可以进一步帮你精确定位应该 catch 哪些异常。欢迎继续提问!