스프링 전환 계획 수립 (iss-cb35afc33813)

This commit is contained in:
forge-bot 2026-07-14 04:35:47 +00:00
parent 3ae50f0a51
commit 6a81dae90b

View file

@ -0,0 +1,95 @@
package com.runtime.core.exception;
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;
/**
* 전역 예외 처리 핸들러
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
ErrorResponse error = ErrorResponse.builder()
.timestamp(LocalDateTime.now())
.status(ex.getStatus().value())
.error(ex.getErrorCode())
.message(ex.getMessage())
.build();
return ResponseEntity.status(ex.getStatus()).body(error);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach(error -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
ErrorResponse error = ErrorResponse.builder()
.timestamp(LocalDateTime.now())
.status(HttpStatus.BAD_REQUEST.value())
.error("VALIDATION_ERROR")
.message("입력 검증에 실패했습니다")
.validationErrors(errors)
.build();
return ResponseEntity.badRequest().body(error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
ErrorResponse error = ErrorResponse.builder()
.timestamp(LocalDateTime.now())
.status(HttpStatus.INTERNAL_SERVER_ERROR.value())
.error("INTERNAL_ERROR")
.message("예상치 못한 오류가 발생했습니다")
.build();
return ResponseEntity.internalServerError().body(error);
}
}
/**
* 비즈니스 예외 기본 클래스
*/
class BusinessException extends RuntimeException {
private final HttpStatus status;
private final String errorCode;
public BusinessException(String message, HttpStatus status, String errorCode) {
super(message);
this.status = status;
this.errorCode = errorCode;
}
public BusinessException(String message, HttpStatus status) {
this(message, status, "BUSINESS_ERROR");
}
public HttpStatus getStatus() { return status; }
public String getErrorCode() { return errorCode; }
}
/**
* 표준 에러 응답 DTO
*/
@lombok.Data
@lombok.Builder
@lombok.AllArgsConstructor
@lombok.NoArgsConstructor
class ErrorResponse {
private LocalDateTime timestamp;
private int status;
private String error;
private String message;
private Map<String, String> validationErrors;
}