-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
deploy-be: cruru version 1.1.2 운영 서버 배포 (v24.10.14) (#812)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: HyungHoKim00 <[email protected]> Co-authored-by: Do Yeop Kim <[email protected]> Co-authored-by: Kwoun Ki Ho <[email protected]>
- Loading branch information
1 parent
6f6c7e3
commit f95f65b
Showing
53 changed files
with
794 additions
and
468 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
backend/src/main/java/com/cruru/advice/ExceptionCallback.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.cruru.advice; | ||
|
||
@FunctionalInterface | ||
public interface ExceptionCallback { | ||
|
||
void handleException(Exception e); | ||
} |
120 changes: 72 additions & 48 deletions
120
backend/src/main/java/com/cruru/advice/GlobalExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,100 @@ | ||
package com.cruru.advice; | ||
|
||
import com.cruru.global.util.ExceptionLogger; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import com.cruru.global.util.MdcUtils; | ||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import lombok.RequiredArgsConstructor; | ||
import java.util.stream.Collectors; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.slf4j.MDC; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.HttpStatusCode; | ||
import org.springframework.http.ProblemDetail; | ||
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 org.springframework.web.context.request.RequestContextHolder; | ||
import org.springframework.web.context.request.ServletRequestAttributes; | ||
import org.springframework.web.context.request.WebRequest; | ||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; | ||
|
||
@Slf4j | ||
@RestControllerAdvice | ||
@RequiredArgsConstructor | ||
public class GlobalExceptionHandler { | ||
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { | ||
|
||
private final UncatchedExceptionHandler handler; | ||
private static final int STACK_TRACE_LIMIT = 5; | ||
|
||
@ExceptionHandler(CruruCustomException.class) | ||
public ResponseEntity<ProblemDetail> handleCustomException(CruruCustomException e) { | ||
HttpServletRequest request = getCurrentHttpRequest(); | ||
ExceptionLogger.info(request, e); | ||
|
||
public ResponseEntity<Object> handleCustomException(CruruCustomException e) { | ||
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(e.getStatus(), e.getMessage()); | ||
return ResponseEntity.of(problemDetail).build(); | ||
|
||
return handleExceptionWithMdc(e, problemDetail, | ||
ex -> log.info("CRURU_EXCEPTION [errorMessage = {}]", ex.getMessage()) | ||
); | ||
} | ||
|
||
@ExceptionHandler(Exception.class) | ||
public ResponseEntity<ProblemDetail> handleUnexpectedException(Exception e, WebRequest request) { | ||
ProblemDetail problemDetail = handleException(e, request); | ||
HttpStatus statusCode = HttpStatus.valueOf(problemDetail.getStatus()); | ||
if (statusCode.is5xxServerError()) { | ||
ExceptionLogger.error(problemDetail); | ||
} else { | ||
ExceptionLogger.warn(problemDetail); | ||
} | ||
ProblemDetail detailsToSend = ProblemDetail.forStatus(statusCode); | ||
return ResponseEntity.of(detailsToSend).build(); | ||
public ResponseEntity<Object> handleUnexpectedException(Exception e) { | ||
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류입니다."); | ||
|
||
return handleExceptionWithMdc(e, problemDetail, | ||
ex -> log.error("SERVER_EXCEPTION [errorMessage = {}, stackTrace = {}]", | ||
ex.getMessage(), | ||
getLimitedStackTrace(ex)) | ||
); | ||
} | ||
|
||
private ProblemDetail handleException(Exception e, WebRequest request) { | ||
try { | ||
ProblemDetail problemDetail = (ProblemDetail) Objects.requireNonNull(handler.handleException(e, request)) | ||
.getBody(); | ||
problemDetail.setProperties(setDetails(getCurrentHttpRequest(), e, HttpStatus.INTERNAL_SERVER_ERROR)); | ||
return problemDetail; | ||
} catch (Exception ex) { | ||
return ProblemDetail.forStatusAndDetail( | ||
HttpStatus.INTERNAL_SERVER_ERROR, | ||
"예기치 못한 오류가 발생하였습니다." | ||
); | ||
private String getLimitedStackTrace(Exception e) { | ||
StackTraceElement[] stackTraceElements = e.getStackTrace(); | ||
|
||
return Arrays.stream(stackTraceElements) | ||
.limit(STACK_TRACE_LIMIT) | ||
.map(StackTraceElement::toString) | ||
.collect(Collectors.joining()); | ||
} | ||
|
||
@Override | ||
protected ResponseEntity<Object> handleMethodArgumentNotValid( | ||
MethodArgumentNotValidException e, | ||
HttpHeaders headers, | ||
HttpStatusCode status, | ||
WebRequest request | ||
) { | ||
Map<String, String> validation = new HashMap<>(); | ||
for (FieldError fieldError : e.getFieldErrors()) { | ||
validation.put(fieldError.getField(), fieldError.getDefaultMessage()); | ||
} | ||
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, validation.toString()); | ||
|
||
return handleExceptionWithMdc(e, problemDetail, | ||
ex -> log.warn("METHOD_ARGUMENT_EXCEPTION [errorMessage = {}]", validation) | ||
); | ||
} | ||
|
||
private HttpServletRequest getCurrentHttpRequest() { | ||
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); | ||
@Override | ||
protected ResponseEntity<Object> handleExceptionInternal( | ||
Exception e, | ||
Object body, | ||
HttpHeaders headers, | ||
HttpStatusCode statusCode, | ||
WebRequest request | ||
) { | ||
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(statusCode, "오류가 발생했습니다. 다시 시도해 주세요."); | ||
|
||
return handleExceptionWithMdc(e, problemDetail, | ||
ex -> log.warn("SPRING_BASIC_EXCEPTION [errorMessage = {}]", ex.getMessage()) | ||
); | ||
} | ||
|
||
private static Map<String, Object> setDetails(HttpServletRequest request, Exception exception, HttpStatus status) { | ||
StackTraceElement origin = exception.getStackTrace()[0]; | ||
Map<String, Object> map = new HashMap<>(); | ||
map.put("httpMethod", request.getMethod()); | ||
map.put("requestUri", request.getRequestURI()); | ||
map.put("statusCode", status.toString()); | ||
map.put("sourceClass", origin.getClassName()); | ||
map.put("sourceMethod", origin.getMethodName()); | ||
map.put("exceptionClass", exception.getClass().getSimpleName()); | ||
map.put("exceptionMessage", exception.getMessage()); | ||
return map; | ||
private ResponseEntity<Object> handleExceptionWithMdc( | ||
Exception e, | ||
ProblemDetail problemDetail, | ||
ExceptionCallback callback | ||
) { | ||
MdcUtils.setMdcForException(e, problemDetail); | ||
callback.handleException(e); | ||
MDC.clear(); | ||
return ResponseEntity.of(problemDetail).build(); | ||
} | ||
} |
Oops, something went wrong.