티스토리 뷰
1. Global Exception Handler
GlobalExceptionHandler는 애플리케이션에서 발생하는 다양한 예외를 중앙에서 관리하고 처리하기 위한 클래스입니다. Spring에서는 @RestControllerAdvice와 @ExceptionHandler를 활용하여 전역 예외 처리를 구현합니다.
주요 기능
- 특정 예외(CoreException)에 대해 맞춤형 응답을 반환.
- 예외의 종류에 따라 적절한 HTTP 상태 코드를 매핑.
- 애플리케이션의 나머지 부분에 영향을 주지 않고 예외를 처리하며 로그를 기록.
- 예상치 못한 예외는 handleAllExceptions에서 처리.
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(CoreException.class)
public ResponseEntity<ErrorResponse> handleCoreException(CoreException coreException) {
logError(coreException.getErrorType());
ErrorResponse errorResponse = new ErrorResponse(
coreException.getErrorType().getErrorCode(),
coreException.getErrorType().getMessage(),
coreException.getPayload()
);
HttpStatus status = mapToHttpStatus(coreException.getErrorType().getErrorCode());
return new ResponseEntity<>(errorResponse, status);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAllExceptions(Exception exception) {
log.warn("Exception occur: ", exception);
ErrorResponse errorResponse = new ErrorResponse(ErrorCode.DB_ERROR, "서버 내부 오류가 발생했습니다.", null);
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
private HttpStatus mapToHttpStatus(ErrorCode errorCode) {
return switch (errorCode) {
case NOT_FOUND -> HttpStatus.NOT_FOUND;
case CLIENT_ERROR -> HttpStatus.BAD_REQUEST;
default -> HttpStatus.INTERNAL_SERVER_ERROR;
};
}
private void logError(ErrorType errorType) {
LogLevel logLevel = errorType.getLogLevel();
switch (logLevel) {
case WARN -> log.warn(errorType.getMessage());
case ERROR -> log.error(errorType.getMessage());
default -> log.info(errorType.getMessage());
}
}
}
2. CoreException
CoreException은 사용자 정의 예외 클래스이며, 애플리케이션에서 발생한 오류에 대해 처리할 수 있는 예외를 정의합니다. ErrorType과 payload를 포함하여, 오류 처리에 필요한 정보를 함께 제공합니다.
주요 기능
- 예외의 종류를 정의하는 ErrorType을 포함합니다.
- Payload는 오류와 관련된 추가 데이터를 포함할 수 있는 필드입니다.
- 예외가 발생할 때, ErrorType에 정의된 메시지를 사용하여 예외 메시지를 제공합니다.
public class CoreException extends RuntimeException {
private final ErrorType errorType;
private final Object payload;
public CoreException(ErrorType errorType, Object payload) {
super(errorType.getMessage());
this.errorType = errorType;
this.payload = payload;
}
public ErrorType getErrorType() {
return errorType;
}
public Object getPayload() {
return payload;
}
}
3. ErrorType
ErrorType은 애플리케이션에서 발생할 수 있는 다양한 오류를 정의하는 열거형 클래스입니다. 각 오류는 특정 ErrorCode, 오류 메시지, 그리고 로그 레벨을 함께 정의하여, 일관된 에러 처리를 가능하게 합니다.
주요 기능
- 각 오류에 대한 HTTP 상태 코드와 메시지를 설명을 제공
- 사용자에게 전달할 오류 메시지를 정의합니다.
- 로그 레벨을 정의하여, 오류 발생 시 로그를 남길 때의 중요도를 설정합니다.
@Getter
@RequiredArgsConstructor
public enum ErrorType {
BALANCE_NOT_FOUND(ErrorCode.NOT_FOUND, "잔액을 찾을 수 없습니다.", LogLevel.WARN),
BALANCE_LIMIT_AMOUNT(ErrorCode.CLIENT_ERROR, "충전 금액이 초과되었습니다.", LogLevel.INFO),
BALANCE_LESS_THAN_ZERO(ErrorCode.CLIENT_ERROR, "충전 금액은 0보다 커야 합니다.", LogLevel.INFO),
BALANCE_EXCEEDS_AVAILABLE(ErrorCode.CLIENT_ERROR, "사용하려는 금액이 잔액을 초과할 수 없습니다.", LogLevel.INFO)
...
// 기타 에러 타입 정의
private final ErrorCode errorCode;
private final String message;
private final LogLevel logLevel;
public ErrorCode getErrorCode() {
return errorCode;
}
public String getMessage() {
return message;
}
public LogLevel getLogLevel() {
return logLevel;
}
}
4. ErrorResponse
ErrorResponse는 예외가 발생했을 때 클라이언트에게 반환할 오류 응답 데이터를 정의하는 record입니다. 이를 통해 오류 응답을 간결하게 관리할 수 있습니다.
주요 기능
- 오류의 종류를 정의합니다.
- 오류 메시지를 정의합니다.
- 추가적인 데이터를 포함할 수 있는 필드로, 오류 처리와 관련된 상세 정보를 클라이언트에 전달합니다.
public record ErrorResponse(ErrorCode errorCode, String message, Object payload) {
}
5. ErrorCode
ErrorCode는 애플리케이션에서 발생할 수 있는 HTTP 상태 코드와 그에 대한 설명을 정의하는 열거형 클래스입니다. 이를 통해 오류 발생 시 적절한 상태 코드와 설명을 클라이언트에게 전달할 수 있습니다.
주요 기능
- 각 오류 코드에 대한 설명을 정의합니다. 이를 통해 클라이언트는 오류의 원인을 이해할 수 있습니다.
- 각 오류에 매핑되는 HTTP 상태 코드를 제공합니다.
public enum ErrorCode {
NOT_FOUND("404: 리소스를 찾을 수 없음"),
DB_ERROR("500: 데이터베이스 오류 발생"),
CLIENT_ERROR("400: 클라이언트 요청 오류");
private final String desc;
ErrorCode(String desc) {
this.desc = desc;
}
public String getDesc() {
return desc;
}
}
6. Logging Filter
LoggingFilter는 HTTP 요청 및 응답의 상세 정보를 로깅하는 기능을 제공합니다. 모든 요청과 응답의 내용을 캡처하여 디버깅과 모니터링에 유용합니다.
주요 기능
- 요청의 URL, HTTP 메서드, 바디 등을 캡처하고 로깅.
- 응답의 상태 코드, 헤더, 바디 등을 로깅.
- Spring Filter를 활용하여 요청-응답 흐름의 양쪽을 처리.
@Component
@Slf4j
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(httpServletRequest);
ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(httpServletResponse);
logRequestDetails(wrappedRequest);
chain.doFilter(wrappedRequest, wrappedResponse);
logResponseDetails(wrappedResponse);
wrappedResponse.copyBodyToResponse();
}
private void logRequestDetails(ContentCachingRequestWrapper request) {
log.info("Request URL: " + request.getRequestURI());
log.info("Request Method: " + request.getMethod());
log.info("Request Body: " + new String(request.getContentAsByteArray()));
}
private void logResponseDetails(ContentCachingResponseWrapper response) {
log.info("Response Status: " + response.getStatus());
log.info("Response Body: " + new String(response.getContentAsByteArray()));
}
}
7. Token Interceptor
TokenInterceptor는 요청 헤더에 포함된 token 값의 유효성을 검증하고, 이를 기반으로 요청을 허용하거나 차단하는 역할을 합니다. 특정 경로에 대해 토큰 검증 로직을 적용할 수 있습니다.
주요 기능
- 요청 헤더에서 토큰을 추출.
- 서비스(WaitingQueueService)를 호출하여 토큰의 유효성을 확인.
- 유효하지 않은 토큰일 경우, HTTP 상태 코드를 401 (Unauthorized)로 설정하고 요청 차단.
@Component
@RequiredArgsConstructor
public class TokenInterceptor implements HandlerInterceptor {
private final WaitingQueueService waitingQueueService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
if (!waitingQueueService.getWaitingQueueCheck(token)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
return true;
}
}
8. Web Config
Spring의 WebMvcConfigurer를 활용하여 특정 API 경로에 대해 TokenInterceptor를 적용합니다.
주요 기능
- 인터셉터를 특정 경로(/api/concerts/**)에만 적용하도록 설정.
- 다른 경로에는 영향을 미치지 않음.
@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final TokenInterceptor tokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/api/concerts/**");
}
}
요약
- Global Exception Handler: 예외를 중앙에서 처리하고, 일관된 오류 응답을 반환.
- CoreException: 사용자 정의 예외로, 오류 종류와 추가 정보를 처리.
- ErrorType Enum: 다양한 오류를 정의하고, 각 오류에 대한 메시지와 로깅 수준 설정.
- ErrorResponse: 클라이언트에 반환할 오류 응답 데이터를 정의.
- ErrorCode: 오류 코드와 설명을 정의하여 적절한 상태 코드 제공.
- Logging Filter: HTTP 요청 및 응답을 로깅하여 디버깅과 모니터링을 강화.
- Token Interceptor: 요청 헤더의 토큰을 검증하여 인증되지 않은 요청 차단
끝.
'hhplus' 카테고리의 다른 글
가상 장애 대응 방안 보고서 (0) | 2025.01.03 |
---|---|
부하 테스트 계획 및 시나리오 설정 (1) | 2025.01.03 |
캐시를 적용하면 좋은 시나리오 (0) | 2024.12.30 |
시나리오에서 발생할 수 있는 동시성 이슈 정리 (0) | 2024.12.17 |
인덱스 성능 최적화 👑 (0) | 2024.12.06 |
- Total
- Today
- Yesterday
- Built-in Functions
- combinations
- Method
- find
- Lambda
- isalpha
- Upper
- for
- zip
- Lower
- If
- operators
- permutations
- Python
- function
- bool
- isdigit
- counter
- index
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |