package com.cadlabel.common.exception; import com.cadlabel.common.api.ApiCode; import com.cadlabel.common.api.ApiResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DataAccessException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; import org.springframework.web.HttpMediaTypeNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.resource.NoResourceFoundException; @Slf4j @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(BizException.class) public ResponseEntity> handleBiz(BizException exception) { return ResponseEntity.status(exception.getHttpStatus()) .body(ApiResponse.failure(exception.getCode(), exception.getMessage())); } @ExceptionHandler({ MethodArgumentNotValidException.class, BindException.class, ConstraintViolationException.class, HttpMediaTypeNotSupportedException.class, HttpRequestMethodNotSupportedException.class, IllegalArgumentException.class }) public ResponseEntity> handleBadRequest(Exception exception) { return ResponseEntity.unprocessableEntity() .body(ApiResponse.failure(ApiCode.INVALID_REQUEST, exception.getMessage())); } @ExceptionHandler(MaxUploadSizeExceededException.class) public ResponseEntity> handleMaxUploadSize(MaxUploadSizeExceededException exception) { return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE) .body(ApiResponse.failure(ApiCode.INVALID_REQUEST, "上传文件超过大小限制")); } @ExceptionHandler(DataAccessException.class) public ResponseEntity> handleDataAccess(DataAccessException exception, HttpServletRequest request) { log.error("Database exception at {} {}", request.getMethod(), request.getRequestURI(), exception); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(ApiResponse.failure(ApiCode.INTERNAL_ERROR, "数据库异常")); } @ExceptionHandler({ NoResourceFoundException.class, NoHandlerFoundException.class }) public ResponseEntity> handleNotFound(HttpServletRequest request) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body(ApiResponse.failure(ApiCode.NOT_FOUND, "请求路径不存在: %s %s" .formatted(request.getMethod(), request.getRequestURI()))); } @ExceptionHandler(Exception.class) public ResponseEntity> handleUnknown(Exception exception, HttpServletRequest request) { log.error("Unhandled exception at {} {}", request.getMethod(), request.getRequestURI(), exception); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(ApiResponse.failure(ApiCode.INTERNAL_ERROR, "系统异常")); } }