TA 역할 Spring 경계 smoke (role-ta-live-1522-001)
This commit is contained in:
parent
bab3f337c1
commit
db3560a819
1 changed files with 65 additions and 0 deletions
|
|
@ -0,0 +1,65 @@
|
|||
package com.runtimematrix.config;
|
||||
|
||||
import com.runtimematrix.controller.dto.ErrorResponse;
|
||||
import com.runtimematrix.domain.exception.BusinessException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
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.Instant;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** 전역 예외 처리기 - RFC 7807 Problem Details 형식으로 변환 */
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex, HttpServletRequest request) {
|
||||
String traceId = getOrGenerateTraceId();
|
||||
MDC.put("traceId", traceId);
|
||||
log.warn("[{}] {} - {}", traceId, ex.getErrorCode(), ex.getMessage());
|
||||
|
||||
return ResponseEntity.status(ex.getHttpStatus())
|
||||
.body(ErrorResponse.of(ex.getType(), ex.getErrorCode(), ex.getMessage(),
|
||||
ex.getHttpStatus(), request.getRequestURI(), traceId));
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex, HttpServletRequest request) {
|
||||
String traceId = getOrGenerateTraceId();
|
||||
String detail = ex.getBindingResult().getFieldErrors().stream()
|
||||
.map(FieldError::getDefaultMessage).collect(Collectors.joining("; "));
|
||||
log.warn("[{}] Validation failed: {}", traceId, detail);
|
||||
|
||||
return ResponseEntity.badRequest()
|
||||
.body(ErrorResponse.of("https://api.runtimematrix.com/errors/validation-failed",
|
||||
"validation-failed", "입력 검증에 실패했습니다: " + detail,
|
||||
HttpStatus.BAD_REQUEST.value(), request.getRequestURI(), traceId));
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex, HttpServletRequest request) {
|
||||
String traceId = getOrGenerateTraceId();
|
||||
log.error("[{}] Unexpected error", traceId, ex);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.body(ErrorResponse.of("https://api.runtimematrix.com/errors/internal-server-error",
|
||||
"internal-server-error", "예상치 못한 오류가 발생했습니다.",
|
||||
HttpStatus.INTERNAL_SERVER_ERROR.value(), request.getRequestURI(), traceId));
|
||||
}
|
||||
|
||||
private String getOrGenerateTraceId() {
|
||||
String existing = MDC.get("traceId");
|
||||
return existing != null ? existing : UUID.randomUUID().toString().substring(0, 12);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue