package com.tcm.training.admin.common;
|
|
import cn.dev33.satoken.exception.NotLoginException;
|
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.validation.BindException;
|
import org.springframework.validation.FieldError;
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.IOException;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.time.format.DateTimeParseException;
|
|
@RestControllerAdvice
|
public class GlobalExceptionHandler {
|
|
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
|
@ExceptionHandler(NotLoginException.class)
|
public ApiResponse<Void> handleNotLogin(NotLoginException e, HttpServletRequest request) {
|
log.warn("未登录访问 [{} {}]: {}", request.getMethod(), request.getRequestURI(), e.getMessage());
|
return ApiResponse.fail(401, "未登录");
|
}
|
|
@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
|
public ApiResponse<Void> handleValidate(Exception e, HttpServletRequest request) {
|
log.warn("请求参数校验失败 [{} {}]", request.getMethod(), request.getRequestURI(), e);
|
if (e instanceof MethodArgumentNotValidException) {
|
FieldError fieldError = ((MethodArgumentNotValidException) e).getBindingResult().getFieldError();
|
if (fieldError != null && fieldError.getDefaultMessage() != null) {
|
return ApiResponse.fail(400, fieldError.getDefaultMessage());
|
}
|
}
|
if (e instanceof BindException) {
|
FieldError fieldError = ((BindException) e).getBindingResult().getFieldError();
|
if (fieldError != null && fieldError.getDefaultMessage() != null) {
|
return ApiResponse.fail(400, fieldError.getDefaultMessage());
|
}
|
}
|
return ApiResponse.fail(400, "参数错误");
|
}
|
|
@ExceptionHandler(IllegalArgumentException.class)
|
public ApiResponse<Void> handleIllegalArgument(IllegalArgumentException e, HttpServletRequest request) {
|
log.warn("业务参数异常 [{} {}]: {}", request.getMethod(), request.getRequestURI(), e.getMessage(), e);
|
return ApiResponse.fail(400, e.getMessage());
|
}
|
|
@ExceptionHandler(HttpMessageNotReadableException.class)
|
public ApiResponse<Void> handleHttpMessageNotReadable(HttpMessageNotReadableException e, HttpServletRequest request) {
|
log.warn("请求体解析失败 [{} {}]", request.getMethod(), request.getRequestURI(), e);
|
return ApiResponse.fail(400, resolveReadableMessage(e));
|
}
|
|
@ExceptionHandler(IOException.class)
|
public ApiResponse<Void> handleIO(IOException e, HttpServletRequest request) {
|
log.error("IO异常 [{} {}]", request.getMethod(), request.getRequestURI(), e);
|
return ApiResponse.fail(500, "文件操作失败: " + e.getMessage());
|
}
|
|
@ExceptionHandler(Exception.class)
|
public ApiResponse<Void> handleException(Exception e, HttpServletRequest request) {
|
log.error("未捕获异常 [{} {}]", request.getMethod(), request.getRequestURI(), e);
|
return ApiResponse.fail(500, "服务器内部错误");
|
}
|
|
private String resolveReadableMessage(Throwable throwable) {
|
Throwable current = throwable;
|
while (current != null) {
|
if (current instanceof InvalidFormatException) {
|
String message = resolveTimeFormatMessage(((InvalidFormatException) current).getTargetType());
|
if (message != null) {
|
return message;
|
}
|
}
|
if (current instanceof DateTimeParseException) {
|
return "时间格式错误,请使用 "
|
+ DateTimes.LOCAL_DATE_TIME_PATTERN + " / "
|
+ DateTimes.LOCAL_DATE_PATTERN + " / "
|
+ DateTimes.LOCAL_TIME_PATTERN;
|
}
|
current = current.getCause();
|
}
|
return "请求参数格式错误";
|
}
|
|
private String resolveTimeFormatMessage(Class<?> targetType) {
|
if (targetType == null) {
|
return null;
|
}
|
if (LocalDateTime.class.isAssignableFrom(targetType)) {
|
return "时间格式错误,需 " + DateTimes.LOCAL_DATE_TIME_PATTERN;
|
}
|
if (LocalDate.class.isAssignableFrom(targetType)) {
|
return "日期格式错误,需 " + DateTimes.LOCAL_DATE_PATTERN;
|
}
|
if (LocalTime.class.isAssignableFrom(targetType)) {
|
return "时间格式错误,需 " + DateTimes.LOCAL_TIME_PATTERN;
|
}
|
return null;
|
}
|
}
|