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

Java SpringBoot中返回HTTP客户端/服务端错误该记录日志还是抛异常?

微服务跨服务调用错误的日志记录与异常抛出选择方案

首先给出明确结论:两者不是二选一的互斥选项,绝大多数场景需要搭配使用,具体可以按照错误类型分层执行对应的处理逻辑。

1 先明确两类操作的核心作用

  • 记录日志:核心是留存故障现场,方便后续排查定位问题,日志内容必须包含足够的上下文信息
  • 抛出异常:核心是中断当前非法流程,让上层调用方感知故障,触发适配的降级/重试/回滚逻辑

2 不同错误场景的处理规则

2.1 目标服务无响应(超时、连接失败、断网)

  • 第一步:优先记录ERROR级别的日志,必须包含的字段:调用的目标服务名、请求接口路径、请求参数、全链路请求ID、超时时间、当前服务节点信息
  • 第二步:抛出自定义的ServiceUnavailableException类型的运行时异常,如果你使用了Spring Cloud相关熔断组件,这类自定义异常可以直接被组件识别,用于统计错误率触发降级规则
  • 注意:绝对不要只记日志不抛异常,否则上层业务逻辑会默认调用成功,大概率会产生脏数据或者逻辑错误

2.2 返回HTTP客户端错误(4xx系列)

按照错误原因分类处理:

  • 如果是当前服务传参错误、签名错误、权限配置错误等本服务可修复的问题:记录ERROR级日志,包含入参、返回的4xx具体状态码、目标服务返回的错误详情,幂等接口可以先重试,重试失败再抛出IllegalArgumentException类异常
  • 如果是用户请求的资源不存在、操作无权限、请求参数非法等需要透传给前端的错误:记录WARN级日志,直接将错误信息封装后透传给调用方,不需要额外抛出未捕获的异常
  • 如果你无法判断4xx的产生原因:统一记录完整上下文日志,抛出ClientRequestException自定义异常给上层业务处理

2.3 返回HTTP服务端错误(5xx系列)

  • 第一步:记录ERROR级日志,包含目标服务返回的完整错误响应体、状态码、本次请求的全链路ID
  • 第二步:如果是幂等接口(比如查询类、删除类)可以按预先配置的重试策略执行重试,重试次数耗尽后抛出RemoteServiceInvokeException异常
  • 第三步:如果是写接口(新增、修改、支付类)不要盲目重试,直接抛出异常触发上层的回滚/降级逻辑

3 Spring Boot 中推荐的简化实现方式

可以用@ControllerAdvice全局异常处理器统一拦截跨服务调用抛出的自定义异常,统一做日志落盘、错误信息封装,避免每个业务调用点重复写日志逻辑:

// 自定义跨服务调用异常
public class RemoteInvokeException extends RuntimeException {
    private final int httpStatus;
    private final String targetServiceName;
    // 构造方法、get方法省略
}

// 全局异常处理器
@ControllerAdvice
public class RemoteInvokeExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(RemoteInvokeExceptionHandler.class);

    @ExceptionHandler(RemoteInvokeException.class)
    public ResponseEntity<ErrorResult> handleRemoteInvokeError(RemoteInvokeException e) {
        // 统一记录异常日志
        log.error("调用远程服务失败,服务名:{},HTTP状态码:{},错误信息:{}", 
                e.getTargetServiceName(), e.getHttpStatus(), e.getMessage(), e);
        // 封装统一错误返回值
        ErrorResult result = new ErrorResult(e.getHttpStatus(), "远程服务暂时不可用,请稍后重试");
        return ResponseEntity.status(e.getHttpStatus()).body(result);
    }
}

4 通用避坑提醒

  • 不要只抛异常不记日志:全链路故障排查的时候会完全找不到根因
  • 不要记录无上下文的无效日志:只输出“调用失败”四个字没有任何排查价值
  • 不要吞异常:捕获异常之后只记日志不往上抛,会导致上层业务流程走错误分支
  • 不要把敏感信息(比如用户密码、支付密钥、用户身份证号)打到日志里

内容的提问来源于stack exchange,提问作者user9347049

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:48:03