全局异常处理
Spring Boot 提供了 @RestControllerAdvice 注解和 @ExceptionHandler 注解,用于实现全局异常捕获和处理。前者用于开启全局的异常捕获,后者用于指定捕获哪些异常以及如何处理这些异常。
PIGX 全局异常处理
位置与作用范围
PIGX 提供的全局异常处理位于 pigx-common-sentinel 模块,通过条件注解限制其生效范围。
关键实现要点:
- 模块位置:全局异常处理类位于
pigx-common-sentinel 模块
- 条件限制:
@ConditionalOnExpression 注解限制了全局异常处理只对 OAuth 2.0 的资源服务器有效
- 异常捕获:
@ExceptionHandler 注解可以捕获具体的异常类型,进行相应的格式化处理
- 熔断指标:业务异常通过
Tracer.trace(e); 记录到 Sentinel,作为熔断降级的重要指标
实现示例
@Slf4j
@RestControllerAdvice
@ConditionalOnExpression("${security.oauth2.resource.server-enabled:true}")
public class GlobalExceptionHandler {
/**
* 全局异常处理
* @param e 异常
* @return 统一响应
*/
@ExceptionHandler(Exception.class)
public R handleException(Exception e) {
log.error("全局异常信息:", e);
return R.failed(e.getLocalizedMessage());
}
/**
* 业务异常处理
* @param e 业务异常
* @return 统一响应
*/
@ExceptionHandler(BusinessException.class)
public R handleBusinessException(BusinessException e) {
log.error("业务异常信息:", e);
// 记录到 Sentinel,用于熔断降级
Tracer.trace(e);
return R.failed(e.getMessage());
}
/**
* 参数校验异常处理
* @param e 参数校验异常
* @return 统一响应
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public R handleValidationException(MethodArgumentNotValidException e) {
log.error("参数校验异常:", e);
BindingResult bindingResult = e.getBindingResult();
String message = bindingResult.getAllErrors().get(0).getDefaultMessage();
return R.failed(message);
}
}
💡条件生效说明
全局异常处理通过 @ConditionalOnExpression 注解控制生效范围,仅在 OAuth 2.0 资源服务器模式下启用,避免影响其他类型的服务。
⚠Sentinel 集成
业务异常必须通过 Tracer.trace(e) 方法记录到 Sentinel,这是实现服务熔断、降级等保护机制的重要指标来源。
自定义异常处理
如需自定义异常处理逻辑,可以在业务模块中创建新的 @RestControllerAdvice 类:
@Slf4j
@RestControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(CustomException.class)
public R handleCustomException(CustomException e) {
log.error("自定义异常:", e);
Tracer.trace(e);
return R.failed(e.getCode(), e.getMessage());
}
}
✓最佳实践
建议为不同类型的异常提供专门的处理方法,返回统一的响应格式,便于前端统一处理错误信息。