From e9cd885700d4707374be4e17f1d9989769c26a3d Mon Sep 17 00:00:00 2001 From: forge-bot Date: Thu, 30 Jul 2026 09:39:27 +0000 Subject: [PATCH] =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EB=A7=A4=EC=9E=85=20?= =?UTF-8?q?=EC=8A=B9=EC=9D=B8=20=EA=B2=BD=EB=A1=9C=20Spring=20Boot=203=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20(ACX-E2E-1785394564819)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/GlobalExceptionHandler.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/main/java/com/acquirex/exception/GlobalExceptionHandler.java diff --git a/src/main/java/com/acquirex/exception/GlobalExceptionHandler.java b/src/main/java/com/acquirex/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..d25d1b1 --- /dev/null +++ b/src/main/java/com/acquirex/exception/GlobalExceptionHandler.java @@ -0,0 +1,74 @@ +package com.acquirex.exception; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + * 전역 예외 처리 핸들러 - Spring Boot 3 (jakarta.validation) + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + @ExceptionHandler(AcquisitionNotFoundException.class) + public ResponseEntity> handleAcquisitionNotFound(AcquisitionNotFoundException ex) { + log.error("매입 정보 없음: {}", ex.getMessage()); + return buildErrorResponse(HttpStatus.NOT_FOUND, ex.getMessage()); + } + + @ExceptionHandler(InvalidAcquisitionStateException.class) + public ResponseEntity> handleInvalidAcquisitionState(InvalidAcquisitionStateException ex) { + log.error("유효하지 않은 매입 상태: {}", ex.getMessage()); + return buildErrorResponse(HttpStatus.BAD_REQUEST, ex.getMessage()); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationErrors(MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach(error -> { + String fieldName = ((FieldError) error).getField(); + errors.put(fieldName, error.getDefaultMessage()); + }); + log.error("검증 오류: {}", errors); + Map response = new HashMap<>(); + response.put("timestamp", LocalDateTime.now()); + response.put("status", HttpStatus.BAD_REQUEST.value()); + response.put("error", "Validation Failed"); + response.put("errors", errors); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity> handleGenericException(Exception ex) { + log.error("예상치 못한 오류 발생", ex); + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "예상치 못한 오류가 발생했습니다"); + } + + private ResponseEntity> buildErrorResponse(HttpStatus status, String message) { + Map response = new HashMap<>(); + response.put("timestamp", LocalDateTime.now()); + response.put("status", status.value()); + response.put("error", status.getReasonPhrase()); + response.put("message", message); + return ResponseEntity.status(status).body(response); + } +} + +/** 매입 정보를 찾을 수 없을 때 발생하는 예외 */ +class AcquisitionNotFoundException extends RuntimeException { + public AcquisitionNotFoundException(String message) { super(message); } +} + +/** 매입 상태가 유효하지 않을 때 발생하는 예외 */ +class InvalidAcquisitionStateException extends RuntimeException { + public InvalidAcquisitionStateException(String message) { super(message); } +} \ No newline at end of file