项目中异常什么时候打印错误和抛出?

大学生学习记录,如有错误或不足,欢迎指出,感谢!

主要分情况,一般是系统异常或者业务异常。

系统异常(数据库/Redis/网络/空指针等未知错误)

必须:log.error(关键信息,异常 e) + 抛出 自定义系统异常

  • 一定要把异常堆栈 e 打出来,不然上线出问题查不到原因
  • 抛一个有名字的异常(如SystemException),方便全局识别

系统异常写法

java 复制代码
@Service
public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);

    public Order getOrder(Long orderId) {
        try {
            // 数据库操作,可能抛SQL异常/空指针
            return orderMapper.selectById(orderId);
        } catch (Exception e) {
            // ✅ 必须:打印错误日志 + 带上完整异常堆栈e
            log.error("查询订单异常,orderId:{}", orderId, e);
            // ✅ 然后抛一个有名字的自定义异常
            throw new SystemException("查询订单失败,请稍后再试");
        }
    }
}

业务异常(参数错误/订单不存在/库存不足等预期内错误)

只抛自定义业务异常,不打 log.error

  • 业务异常是正常流程里的判断,不是bug,不用打堆栈
  • 全局异常处理器里打个 log.warn提示就行,避免日志泛滥。
vbnet 复制代码
public Order createOrder(Order order) {
    // 业务判断,预期内的错误
    if (order.getUserId() == null) {
        // ✅ 只抛业务异常,不打log.error!
        throw new BizException("用户ID不能为空");
    }
    if (order.getProductCount() <= 0) {
        throw new BizException("商品数量必须大于0");
    }
    return orderMapper.insert(order);
}

为什么业务异常不打log.error?

  • 业务异常是正常逻辑,不是程序bug
  • 如果你每个校验都打 error, 日志文件会瞬间爆炸
  • 全局异常处理器打个warn就够了

全局异常处理类写法

一般controller 不捕获异常,交给这里的带有@RestControllerAdvice注解异常处理类。

kotlin 复制代码
// 全局异常处理类(整个项目只写这1次)
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 捕获【业务异常】
    @ExceptionHandler(BizException.class)
    public Result<Void> handleBizException(BizException e) {
        // 日志只在这里打一次
        log.warn("业务异常:{}", e.getMessage());
        // 统一返回前端
        return Result.fail(e.getMessage());
    }

    // 捕获【所有系统异常】
    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        log.error("系统异常", e);
        return Result.fail("服务器繁忙,请稍后再试");
    }
}

注意的细节点

  1. log.error 必须带上 e

java

运行

c 复制代码
// 错误(没有堆栈,上线等于没日志)
log.error("查询订单失败");

// 正确(带完整异常堆栈,能定位代码行)
log.error("查询订单失败,orderId:{}", orderId, e);
  1. **抛的异常必须 "有名字"**不要抛Exception或RuntimeException,要抛自定义的:
  • SystemException(系统错误)
  • BizException(业务错误)全局处理器才能分开处理,返回不同提示。
相关推荐
程序猿DD3 小时前
OctaFuse Gateway 2.15.0:MCP 聚合、向量 Embeddings 与官方目录同步
后端·agent
余槐i5 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
需要8266 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
凤山老林7 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
伯恩bourne8 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
张彦峰ZYF8 小时前
停顿短不等于延迟低:G1、ZGC 与低延迟服务的目标分野、代价账本与选型标定
后端·回收暂停、应用停止总时长·到达安全点、分配停滞·屏障吃吞吐、并发线程吃核心·并发窗口吃堆余量·分区式靠挑回收集兑现目标·染色指针式不支持压缩引用
pride.li8 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
upala9 小时前
【仓颉语言入门 · 第二篇 第 6 课】
后端
罗丹丹Luna9 小时前
移动端显示“已提交”以后:SAP 与低代码集成该怎样暴露真实状态
后端·架构
码事漫谈9 小时前
因为太想讨好你,所以AI会骗你
后端