-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: YSL-13 RootExceptionHandler 및 Problem 적용 (#10)
* feat: 에러 공통화를 위한 problme 도입 * feat: 500 에러 추가 * feat: 유효성 검증에 실패한 내용 관련 400 에러 추가 * chore: 마지막 라인 추가 * chore: build.gradle 순서 정리 * refactor: Status import 제거 * refactor: foreach문 map으로 개선
- Loading branch information
1 parent
b3a7581
commit d383ecf
Showing
4 changed files
with
125 additions
and
1 deletion.
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
19 changes: 19 additions & 0 deletions
19
src/main/java/org/idiot/yesslave/global/exception/InvalidResponse.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,19 @@ | ||
package org.idiot.yesslave.global.exception; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
@Schema(description = "입력된 값에 대한 유효성 검사에 실패했을 경우의 응답값") | ||
public class InvalidResponse { | ||
@Schema(description = "오류가 발생한 field명", example = "verificationCode") | ||
private String field; | ||
|
||
@Schema(description = "오류 메세지", example = "확인번호를 입력해주세요.") | ||
private String message; | ||
|
||
@Schema(description = "잘못 입력된 field 입력 값", example = "ABCDE") | ||
private Object rejectValue; | ||
} |
93 changes: 93 additions & 0 deletions
93
src/main/java/org/idiot/yesslave/global/exception/RootExceptionHandler.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,93 @@ | ||
package org.idiot.yesslave.global.exception; | ||
|
||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.validation.BindingResult; | ||
import org.springframework.web.bind.MethodArgumentNotValidException; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.zalando.problem.Problem; | ||
import org.zalando.problem.Status; | ||
|
||
import javax.validation.ConstraintViolationException; | ||
import java.util.List; | ||
|
||
@Slf4j | ||
@ControllerAdvice | ||
@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class) | ||
public class RootExceptionHandler { | ||
@ExceptionHandler(Exception.class) | ||
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) | ||
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = { | ||
@Content(schema = @Schema(implementation = Problem.class)) | ||
}) | ||
public ResponseEntity<Problem> exceptionHandler(Exception e) { | ||
|
||
log.error("[ 500 ERROR ] : ", e); | ||
|
||
Problem problem = Problem.builder() | ||
.withStatus(Status.INTERNAL_SERVER_ERROR) | ||
.withTitle(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()) | ||
.withDetail(e.getMessage()) | ||
.build(); | ||
|
||
return ResponseEntity | ||
.status(HttpStatus.INTERNAL_SERVER_ERROR) | ||
.body(problem); | ||
} | ||
|
||
@ResponseStatus(value = HttpStatus.BAD_REQUEST) | ||
@ApiResponse(responseCode = "400", description = "Bad Request", content = { | ||
@Content(schema = @Schema(implementation = InvalidResponse.class)) | ||
}) | ||
@ExceptionHandler(MethodArgumentNotValidException.class) | ||
public ResponseEntity<Problem> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { | ||
log.error("[ 400 ERROR ] : ", e); | ||
|
||
BindingResult bindingResult = e.getBindingResult(); | ||
|
||
List<InvalidResponse> responses = bindingResult.getFieldErrors().stream() | ||
.map(fieldError -> new InvalidResponse(fieldError.getField() | ||
, fieldError.getDefaultMessage() | ||
, fieldError.getRejectedValue()) | ||
).toList(); | ||
|
||
Problem problem = Problem.builder() | ||
.withStatus(Status.BAD_REQUEST) | ||
.withTitle(Status.BAD_REQUEST.getReasonPhrase()) | ||
.with("parameters", responses) | ||
.build(); | ||
|
||
return ResponseEntity | ||
.status(HttpStatus.BAD_REQUEST) | ||
.body(problem); | ||
} | ||
|
||
@ResponseStatus(value = HttpStatus.BAD_REQUEST) | ||
@ApiResponse(responseCode = "400", description = "Bad Request", content = { | ||
@Content(schema = @Schema(implementation = InvalidResponse.class)) | ||
}) | ||
@ExceptionHandler(ConstraintViolationException.class) | ||
public Problem constraintViolationExceptionHandler(ConstraintViolationException e) { | ||
log.error("[ 400 ERROR ] : ", e); | ||
|
||
List<InvalidResponse> responses = e.getConstraintViolations().stream() | ||
.map(fieldError -> new InvalidResponse(fieldError.getPropertyPath().toString() | ||
, fieldError.getMessage() | ||
, fieldError.getInvalidValue()) | ||
).toList(); | ||
|
||
return Problem.builder() | ||
.withStatus(Status.BAD_REQUEST) | ||
.withTitle(Status.BAD_REQUEST.getReasonPhrase()) | ||
.with("parameters", responses) | ||
.build(); | ||
} | ||
} |
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