178 lines
7.1 KiB
Java
178 lines
7.1 KiB
Java
package cn.palmte.work.config;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.dao.DataAccessException;
|
|
import org.springframework.dao.DataAccessResourceFailureException;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.util.ObjectUtils;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
|
import org.springframework.http.converter.HttpMessageNotWritableException;
|
|
import org.springframework.transaction.TransactionSystemException;
|
|
import org.springframework.validation.BindException;
|
|
import org.springframework.validation.BindingResult;
|
|
import org.springframework.validation.FieldError;
|
|
import org.springframework.validation.ObjectError;
|
|
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
|
import org.springframework.web.bind.MissingServletRequestParameterException;
|
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
|
import org.springframework.web.multipart.MultipartException;
|
|
|
|
import java.sql.SQLException;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import cn.palmte.work.ErrorMessage;
|
|
import cn.palmte.work.ErrorMessageException;
|
|
import cn.palmte.work.Json;
|
|
import cn.palmte.work.Result;
|
|
import cn.palmte.work.ValidationError;
|
|
import cn.palmte.work.controller.backend.ProcessController;
|
|
|
|
/**
|
|
* 异常处理
|
|
*
|
|
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
|
|
* @since 2.0 2022/12/30 15:24
|
|
*/
|
|
@RestControllerAdvice(assignableTypes = ProcessController.class)
|
|
public class ApplicationExceptionHandler {
|
|
private static final Logger log = LoggerFactory.getLogger(ApplicationExceptionHandler.class);
|
|
|
|
public static final ErrorMessage argsErrorMessage = ErrorMessage.failed("参数错误");
|
|
public static final ErrorMessage sizeExceeded = ErrorMessage.failed("上传文件大小超出限制");
|
|
public static final ErrorMessage methodNotSupported = ErrorMessage.failed("请求方式不支持");
|
|
public static final ErrorMessage internalServerError = ErrorMessage.failed("服务器内部异常");
|
|
public static final ErrorMessage notWritableError = ErrorMessage.failed("数据无法正常返回到客户端");
|
|
|
|
@ExceptionHandler(ErrorMessageException.class)
|
|
public ResponseEntity<ErrorMessage> errorMessage(ErrorMessageException errorMessage) {
|
|
HttpStatus httpStatus = errorMessage.getStatus();
|
|
return ResponseEntity.status(httpStatus)
|
|
.body(ErrorMessage.failed(errorMessage.getMessage()));
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler(IllegalArgumentException.class)
|
|
public ErrorMessage badRequest(IllegalArgumentException exception) {
|
|
return ErrorMessage.failed(exception.getMessage());
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler({ MaxUploadSizeExceededException.class })
|
|
public ErrorMessage badRequest() {
|
|
return sizeExceeded;
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
|
public ErrorMessage methodNotSupported() {
|
|
return methodNotSupported;
|
|
}
|
|
|
|
@ExceptionHandler
|
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
public ErrorMessage error(Exception exception) {
|
|
log.error("An Exception occurred", exception);
|
|
if (exception instanceof SQLException) {
|
|
return internalServerError;
|
|
}
|
|
if (exception instanceof HttpMessageNotWritableException) {
|
|
return notWritableError;
|
|
}
|
|
if (exception instanceof TransactionSystemException) {
|
|
return ErrorMessage.failed("数据库出错");
|
|
}
|
|
return ErrorMessage.failed(exception.getMessage());
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
|
public ErrorMessage typeMismatch(MethodArgumentTypeMismatchException mismatch) {
|
|
return ErrorMessage.failed("参数'" + mismatch.getName() + "'不能转换到对应类型");
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler(MissingServletRequestParameterException.class)
|
|
public ErrorMessage parameterError(MissingServletRequestParameterException e) {
|
|
return ErrorMessage.failed("缺少参数'" + e.getParameterName() + "'");
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler({
|
|
MultipartException.class,
|
|
HttpMessageNotReadableException.class,
|
|
HttpMediaTypeNotSupportedException.class
|
|
})
|
|
public ErrorMessage messageNotReadable() {
|
|
return argsErrorMessage;
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
@ExceptionHandler({ BindException.class, MethodArgumentNotValidException.class })
|
|
public Result validExceptionHandler(Exception e) {
|
|
|
|
BindingResult result;
|
|
if (e instanceof MethodArgumentNotValidException) {
|
|
result = ((MethodArgumentNotValidException) e).getBindingResult();
|
|
}
|
|
else if (e instanceof BindException) {
|
|
result = (BindingResult) e;
|
|
}
|
|
else {
|
|
return ErrorMessage.failed();
|
|
}
|
|
List<ObjectError> allErrors = result.getAllErrors();
|
|
Map<String, String> model = new HashMap<>(16);
|
|
|
|
for (ObjectError error : allErrors) {
|
|
if (error instanceof FieldError) {
|
|
FieldError fieldError = (FieldError) error;
|
|
String field = fieldError.getField();
|
|
String defaultMessage = error.getDefaultMessage();
|
|
model.put(field, defaultMessage);
|
|
// log.error("[{}] -> [{}]", field, defaultMessage);
|
|
}
|
|
}
|
|
return ValidationError.failed(model);
|
|
}
|
|
|
|
@ExceptionHandler(NullPointerException.class)
|
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
public Json nullPointer(NullPointerException exception) {
|
|
log.error("An Exception occurred", exception);
|
|
final StackTraceElement[] stackTrace = exception.getStackTrace();
|
|
if (ObjectUtils.isEmpty(stackTrace)) {
|
|
return Json.failed("空指针", "暂无堆栈信息");
|
|
}
|
|
return Json.failed("空指针", stackTrace[0]);
|
|
}
|
|
|
|
@ExceptionHandler(DataAccessException.class)
|
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
public ErrorMessage dataAccessException(DataAccessException accessException) {
|
|
String message = getDataAccessMessage(accessException.getCause());
|
|
log.error(message, accessException);
|
|
return ErrorMessage.failed(message);
|
|
}
|
|
|
|
String getDataAccessMessage(Throwable cause) {
|
|
return "数据库出错";
|
|
}
|
|
|
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
@ExceptionHandler(DataAccessResourceFailureException.class)
|
|
public ErrorMessage dataAccessException(DataAccessResourceFailureException accessException) {
|
|
log.error("数据库连接出错", accessException);
|
|
return ErrorMessage.failed("数据库连接出错");
|
|
}
|
|
}
|