Skip to content

feat: Added GlobalExceptionHandler #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.f_lab.la_planete.controller;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.persistence.PessimisticLockException;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.exception.LockTimeoutException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.web.ErrorResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@Hidden
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(IllegalStateException.class)
public ResponseEntity<ErrorResponse> handleIllegalStateException(IllegalStateException e) {
return ResponseEntity
.status(HttpStatus.CONFLICT)
.body(ErrorResponse.of(e.getMessage(), HttpStatus.CONFLICT.value()));
}

/**
* 데이터베이스 관련 예외 (e.g. 주로 락을 얻는 대기시간이 오래되어서 요청을 반환할 때)
*/
@ExceptionHandler(JpaSystemException.class)
public ResponseEntity<ErrorResponse> handleJpaSystemException(JpaSystemException e) {
log.error("JpaSystemException occurred", e);
return ResponseEntity
.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(ErrorResponse.of(
"현재 너무 많은 요청을 처리하고 있습니다. 다시 시도해주세요",
HttpStatus.SERVICE_UNAVAILABLE.value()));
}

/**
* 어플리케이션에서 처리하지 못한 다른 모든 예외
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception e) {
log.error("Unexpected Error occurred. Requires Potential Handling", e);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ErrorResponse.of(
"알 수 없는 오류가 발생했습니다. 다시 시도해주세요",
HttpStatus.INTERNAL_SERVER_ERROR.value()));
}

@Getter
@AllArgsConstructor
static class ErrorResponse {
private String message;

@JsonProperty("status_code")
private int statusCode;

public static ErrorResponse of(String message, int statusCode) {
return new ErrorResponse(message, statusCode);
}
}
}
7 changes: 1 addition & 6 deletions src/main/java/com/f_lab/la_planete/service/OrderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,7 @@ public OrderCreateResponseDTO createFoodOrder(OrderCreateRequestDTO request) {
}

private Food findFoodWithLock(Long foodId) {
try {
return foodRepository.findFoodByFoodIdWithPessimisticLock(foodId);
} catch(PessimisticLockException | PessimisticLockingFailureException e) {
log.warn("Pessimistic lock failure on food ID: {}", foodId, e);
throw new IllegalStateException("오류 다시 시도해 주시길 바랍니다.");
}
return foodRepository.findFoodByFoodIdWithPessimisticLock(foodId);
}
}

Loading