自定义业务异常类需继承runtimeexception,避免强制try-catch;在service层校验失败时主动throw businessexception;配合@controlleradvice统一处理并返回标准json响应。

<p>自定义业务异常类,核心是继承 <strong>RuntimeException</strong>(非检查异常),避免强制 try-catch 干扰业务主流程;在关键校验或规则不满足时,用 <strong>throw</strong> 主动抛出,交由统一异常处理器处理。</p>
<h3>定义业务异常类</h3>
<p>新建一个类,比如 <strong>BusinessException</strong>,继承 <strong>RuntimeException</strong>,提供带状态码、错误信息、可选详情的构造方法:</p>
<p><font color="#888">示例代码:</font></p>
<pre class="brush:php;toolbar:false;"><code>public class BusinessException extends RuntimeException {
private final int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public BusinessException(int code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
public int getCode() {
return code;
}
}</code>
在 Service 层核心逻辑中主动 throw
不要等到系统出错才抛异常,而是在业务规则被违反时立即中断流程。比如用户余额不足、订单已取消、参数非法等场景:
- 校验失败就 throw,不继续执行后续逻辑
- 异常信息要明确,便于前端或日志定位问题
- 避免用 new Exception() 或 throw new RuntimeException("xxx") 这类通用异常
示例:
<code>public void payOrder(Long orderId, BigDecimal amount) {
Order order = orderMapper.selectById(orderId);
if (order == null) {
throw new BusinessException(4001, "订单不存在");
}
if (!"UNPAID".equals(order.getStatus())) {
throw new BusinessException(4002, "订单状态不允许支付,当前状态:" + order.getStatus());
}
if (order.getAmount().compareTo(amount) != 0) {
throw new BusinessException(4003, "支付金额与订单金额不匹配");
}
// 执行扣款、更新状态等...
}</code>
配合全局异常处理器统一响应
Spring Boot 中建议配一个 @ControllerAdvice,捕获 BusinessException 并返回标准 JSON:
- 返回一致的状态码(如 HTTP 200)、业务码(code)、提示信息(message)
- 不暴露堆栈,避免敏感信息泄露
- 其他未捕获异常(如空指针)可兜底处理
示例片段:
<code>@ExceptionHandler(BusinessException.class)
@ResponseBody
public Result> handleBusinessException(BusinessException e) {
return Result.fail(e.getCode(), e.getMessage());
}</code>
注意事项
- 不要把 BusinessException 当作控制流工具(比如大量用于“正常分支”),它代表的是异常情况
- 状态码建议按模块分段定义(如 4001~4099 为订单模块),方便归类和排查
- 日志中建议记录异常对象(包括 code 和 message),但一般不打印 stackTrace
- 若需支持国际化,可在构造时传入 i18n key,由处理器解析成对应语言文案











