自定义业务异常类需继承RuntimeException,提供含错误消息和可选错误码的构造方法,并在Service层主动抛出以拦截非法业务状态。
自定义业务异常类,核心是继承 runtimeexception(或 exception),并提供带业务含义的构造方法;在业务逻辑中,用 throw 主动抛出该异常,由统一异常处理器捕获并返回友好结果。
定义业务异常类(推荐继承 RuntimeException)
避免强制 try-catch,更符合业务异常“非检查型”的语义:
- 新建类如
BusinessException,继承RuntimeException - 至少提供两个构造方法:一个只传错误消息,一个传消息 + 错误码(可选)
- 可添加
errorCode字段和 getter,方便前端区分错误类型
public class BusinessException extends RuntimeException {
private final int errorCode;
<pre class="brush:php;toolbar:false;">public BusinessException(String message) {
super(message);
this.errorCode = 500;
}
public BusinessException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}}
在 Service 层核心逻辑中主动 throw
不是等系统出错才抛,而是主动校验失败时立即 throw:
- 比如用户余额不足、订单已取消、参数不合法等明确的业务规则不满足
- throw 的时机要早——在真正执行前拦截,避免无效处理
- 消息尽量具体(如 “库存不足,当前剩余:2,需求数:5”),便于排查和提示
public void deductStock(Long itemId, Integer quantity) {
Item item = itemMapper.selectById(itemId);
if (item == null) {
throw new BusinessException(404, "商品不存在");
}
if (item.getStock() < quantity) {
throw new BusinessException(400,
String.format("库存不足,当前剩余:%d,需求数:%d", item.getStock(), quantity));
}
item.setStock(item.getStock() - quantity);
itemMapper.updateById(item);
}全局统一捕获并格式化响应
用 @ControllerAdvice + @ExceptionHandler 拦截自定义异常:
- 避免每个接口都 try-catch,保持业务代码干净
- 返回标准 JSON 结构(如 { code: 400, msg: "...", data: null })
- 对 BusinessException 返回对应 errorCode 和 message;其他未预期异常返回 500
@ControllerAdvice
public class GlobalExceptionHandler {
<pre class="brush:php;toolbar:false;">@ResponseBody
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
return Result.fail(e.getErrorCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result<?> handleUnexpectedException(Exception e) {
log.error("系统异常", e);
return Result.fail(500, "系统繁忙,请稍后再试");
}}
注意点与建议
- 不要用异常做流程控制(比如用 catch 来判断是否存在),这是反模式
- 错误码建议分类管理(如 400xx 表参数类,403xx 表权限类),避免硬编码
- 日志记录时,对 BusinessException 可只打 warn 级别,避免刷屏;系统异常才打 error
- 前端根据
errorCode做差异化提示(如跳登录页、弹 toast、高亮输入框)

















