springboot全局异常处理器处理顺序问题
在使用异常处理器时,代码
package com.ecode.handler;
import com.ecode.constant.MessageConstant;
import com.ecode.exception.BaseException;
import com.ecode.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.sql.SQLException;
/**
* 全局异常处理器,处理项目中抛出的业务异常
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 捕获业务异常
* @param ex
* @return
*/
@ExceptionHandler
public Result exceptionHandler(BaseException ex){
log.error("业务异常:{}", ex.getMessage());
return Result.error(ex.getMessage());
}
/**
* @param ex 数据库异常
* @return 后端统一返回结果
*/
@ExceptionHandler
public Result exceptionHandler(SQLException ex){
String message = ex.getMessage();
log.error("数据库异常:{}",message);
if (message.contains("Duplicate entry")){
String username = message.split(" ")[2];
return Result.error(username + MessageConstant.ALREADY_EXISTS);
}else {
return Result.error(MessageConstant.SQL_UNKNOWN_ERROR);
}
}
@ExceptionHandler
public Result exceptionHandler(Exception ex){
log.error("服务器异常:{}",ex.getMessage());
return Result.error("服务器异常");
}
}
当出现数据库异常时,返回
2024-10-05 22:56:13.798 ERROR 26216 --- [nio-8080-exec-4] c.ecode.handler.GlobalExceptionHandler : 服务器异常:
### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'xu*****@foxmail.com' for key 'user.邮箱'
### The error may exist in com/ecode/mapper/UserMapper.java (best guess)
### The error may involve com.ecode.mapper.UserMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO user ( username, password, email, status, name, profile_picture, score, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'xu****@foxmail.com' for key 'user.邮箱'
; Duplicate entry 'xu*****@foxmail.com' for key 'user.邮箱'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'xu*******@foxmail.com' for key 'user.邮箱'
按理说越精确优先级越高,SQLIntegrityConstraintViolationException继承SQLException,为什么返回的却是被Exception异常捕获?求解答
我尝试注释Exception异常捕获,此时异常能被SQLException捕获
你的代码就是错误的,
SQLException
及其子类SQLIntegrityConstraintViolationException
是个检查时异常,你在运行时捕获,是捕获不到的,这个函数永远不会执行的你在日志中看到
SQLIntegrityConstraintViolationException
错误,是MyBatis
输出时,从MyBatisSystemException.getCause()
得到的,实际的异常在返回到控制层时,已经经过了spring-jdbc
和MyBatis
的包装处理,你可以改成这样看看具体的异常类型