-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e4748dc
commit a28df11
Showing
12 changed files
with
428 additions
and
1 deletion.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
src/main/java/ussum/homepage/domain/user/exception/UserNotFoundException.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,11 @@ | ||
package ussum.homepage.domain.user.exception; | ||
|
||
import ussum.homepage.global.error.code.BaseErrorCode; | ||
import ussum.homepage.global.error.exception.GeneralException; | ||
|
||
public class UserNotFoundException extends GeneralException { | ||
private BaseErrorCode baseErrorCode; | ||
public UserNotFoundException(BaseErrorCode baseErrorCode) { | ||
super(baseErrorCode); | ||
} | ||
} |
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,39 @@ | ||
package ussum.homepage.global; | ||
|
||
import ussum.homepage.global.error.code.BaseCode; | ||
import ussum.homepage.global.error.status.SuccessStatus; | ||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public class ApiResponse<T> { | ||
@JsonProperty("isSuccess") | ||
private final Boolean isSuccess; | ||
|
||
private final String code; | ||
private final String message; | ||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
private final T data; | ||
|
||
public static <T> ApiResponse<T> onSuccess(T data) { | ||
return new ApiResponse<>( | ||
true, SuccessStatus._OK.getCode(), SuccessStatus._OK.getMessage(), data); | ||
} | ||
|
||
public static <T> ApiResponse<T> onSuccess(String message, T data) { | ||
return new ApiResponse<>(true, SuccessStatus._OK.getCode(), message, data); | ||
} | ||
|
||
public static <T> ApiResponse<T> onSuccess(BaseCode code, T data) { | ||
return new ApiResponse<>(true, code.getReasonHttpStatus().getCode(), | ||
code.getReasonHttpStatus().getMessage(), data); | ||
} | ||
|
||
public static <T> ApiResponse<T> onFailure(String code, String message, T data) { | ||
return new ApiResponse<>(false, code, message, data); | ||
} | ||
} |
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,9 @@ | ||
package ussum.homepage.global.error.code; | ||
|
||
import ussum.homepage.global.error.dto.ReasonDto; | ||
|
||
public interface BaseCode { | ||
public ReasonDto getReason(); | ||
|
||
public ReasonDto getReasonHttpStatus(); | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/ussum/homepage/global/error/code/BaseErrorCode.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,9 @@ | ||
package ussum.homepage.global.error.code; | ||
|
||
import ussum.homepage.global.error.dto.ErrorReasonDto; | ||
|
||
public interface BaseErrorCode { | ||
public ErrorReasonDto getReason(); | ||
|
||
public ErrorReasonDto getReasonHttpStatus(); | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/ussum/homepage/global/error/dto/ErrorReasonDto.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,15 @@ | ||
package ussum.homepage.global.error.dto; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@Builder | ||
public class ErrorReasonDto { | ||
private HttpStatus httpStatus; | ||
|
||
private final boolean isSuccess; | ||
private final String code; | ||
private final String message; | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/ussum/homepage/global/error/dto/ReasonDto.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,15 @@ | ||
package ussum.homepage.global.error.dto; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@Builder | ||
public class ReasonDto { | ||
private HttpStatus httpStatus; | ||
|
||
private final boolean isSuccess; | ||
private final String code; | ||
private final String message; | ||
} |
187 changes: 187 additions & 0 deletions
187
src/main/java/ussum/homepage/global/error/exception/ExceptionAdvice.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,187 @@ | ||
package ussum.homepage.global.error.exception; | ||
|
||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.validation.ConstraintViolationException; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.TypeMismatchException; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.HttpStatusCode; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.MethodArgumentNotValidException; | ||
import org.springframework.web.bind.MissingServletRequestParameterException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
import org.springframework.web.context.request.ServletWebRequest; | ||
import org.springframework.web.context.request.WebRequest; | ||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; | ||
import ussum.homepage.global.ApiResponse; | ||
import ussum.homepage.global.error.dto.ErrorReasonDto; | ||
import ussum.homepage.global.error.status.ErrorStatus; | ||
|
||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
@Slf4j | ||
@RestControllerAdvice(annotations = {RestController.class}) | ||
public class ExceptionAdvice extends ResponseEntityExceptionHandler { | ||
|
||
/** | ||
* 요청된 타입과 맞지 않는 파라미터가 전달될 때 발생 | ||
* <p> | ||
* 작동 방식: 예외에서 속성 이름을 추출하고, "올바른 값이 아닙니다."라는 메시지와 함께 | ||
* 내부 메소드 handleExceptionInternalMessage로 전달 | ||
*/ | ||
@Override | ||
protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException e, HttpHeaders headers, | ||
HttpStatusCode status, WebRequest request) { | ||
|
||
String errorMessage = e.getPropertyName() + ": 올바른 값이 아닙니다."; | ||
|
||
return handleExceptionInternalMessage(e, headers, request, errorMessage); | ||
} | ||
|
||
/** | ||
* MissingServletRequestParameterException을 처리 | ||
* 이 예외는 필수 요청 파라미터가 누락 되었을 때 발생 | ||
* <p> | ||
* 작동 방식: 누락된 파라미터 이름을 추출하고, 동일한 "올바른 값이 아닙니다." 메시지를 사용하여 처리 | ||
*/ | ||
@Override | ||
protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException e, | ||
HttpHeaders headers, | ||
HttpStatusCode status, WebRequest webRequest) { | ||
|
||
String errorMessage = e.getParameterName() + ": 올바른 값이 아닙니다."; | ||
|
||
return handleExceptionInternalMessage(e, headers, webRequest, errorMessage); | ||
} | ||
|
||
/** | ||
* MethodArgumentNotValidException을 처리 | ||
* 이 예외는 메소드 파라미터의 유효성 검사 실패 시 발생 | ||
* <p> | ||
* 작동 방식: 각 필드 오류에 대한 정보를 수집하고, 이를 ErrorStatus._BAD_REQUEST와 함께 | ||
* handleExceptionInternalArgs 메소드로 전달 | ||
*/ | ||
@Override | ||
public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException e, HttpHeaders headers, | ||
HttpStatusCode status, WebRequest webRequest) { | ||
|
||
Map<String, String> errors = new LinkedHashMap<>(); | ||
|
||
e.getBindingResult().getFieldErrors().stream() | ||
.forEach(fieldError -> { | ||
String fieldName = fieldError.getField(); | ||
String errorMessage = Optional.ofNullable(fieldError.getDefaultMessage()).orElse(""); | ||
|
||
errors.merge( | ||
fieldName, | ||
errorMessage, | ||
(existingErrorMessage, newErrorMessage) -> | ||
existingErrorMessage + ", " + newErrorMessage); | ||
} | ||
); | ||
|
||
return handleExceptionInternalArgs(e, HttpHeaders.EMPTY, ErrorStatus.valueOf("_BAD_REQUEST"), | ||
webRequest, errors); | ||
} | ||
|
||
/** | ||
* ConstraintViolationException을 처리 | ||
* 이 예외는 Bean Validation API에 의해 유효성 검사 실패 시 발생 | ||
* | ||
* 작동 방식: 유효성 검사 위반에 대한 메시지를 수집하고, ErrorStatus.valueOf를 사용하여 적절한 에러 상태(String)로 변환 후, | ||
* handleExceptionInternalConstraint 메소드로 처리 | ||
*/ | ||
@ExceptionHandler | ||
public ResponseEntity<Object> validation(ConstraintViolationException e, WebRequest webRequest) { | ||
String errorMessage = | ||
e.getConstraintViolations().stream() | ||
.map(constraintViolation -> constraintViolation.getMessage()) | ||
.findFirst() | ||
.orElseThrow( | ||
() -> | ||
new RuntimeException( | ||
"ConstraintViolationException 추출 도중 에러 발생")); | ||
|
||
return handleExceptionInternalConstraint(e, ErrorStatus.valueOf(errorMessage), HttpHeaders.EMPTY, webRequest); | ||
} | ||
|
||
/** | ||
* 일반 Exception을 처리 | ||
* 이 메소드는 처리되지 않은 다른 모든 예외를 캡처함 | ||
* | ||
* 작동 방식: 예외의 메시지와 ErrorStatus._INTERNAL_SERVER_ERROR를 사용하여 | ||
* handleExceptionInternalFalse 메소드로 처리합니다. | ||
*/ | ||
@ExceptionHandler | ||
public ResponseEntity<Object> exception(Exception e, WebRequest webRequest) { | ||
e.printStackTrace(); | ||
|
||
return handleExceptionInternalFalse(e, ErrorStatus._INTERNAL_SERVER_ERROR, HttpHeaders.EMPTY, | ||
ErrorStatus._INTERNAL_SERVER_ERROR.getHttpStatus(), webRequest, e.getMessage()); | ||
} | ||
|
||
/** | ||
* 사용자 정의 예외 GeneralException을 처리함 | ||
* | ||
* 작동 방식: GeneralException에서 ErrorReasonDto를 추출하고, | ||
* 이를 handleExceptionInternal 메소드로 전달함 | ||
*/ | ||
@ExceptionHandler(value = GeneralException.class) | ||
public ResponseEntity onThrowException(GeneralException generalException, HttpServletRequest httpServletRequest) { | ||
|
||
ErrorReasonDto errorReasonHttpStatus = generalException.getErrorReasonHttpStatus(); | ||
|
||
return handleExceptionInternal(generalException, errorReasonHttpStatus, null, httpServletRequest); | ||
} | ||
|
||
private ResponseEntity<Object> handleExceptionInternal(Exception e, ErrorReasonDto reason, | ||
HttpHeaders httpHeaders, | ||
HttpServletRequest httpServletRequest) { | ||
|
||
ApiResponse<Object> body = ApiResponse.onFailure(reason.getCode(), reason.getMessage(), null); | ||
WebRequest webRequest = new ServletWebRequest(httpServletRequest); | ||
|
||
return super.handleExceptionInternal(e, body, httpHeaders, reason.getHttpStatus(), webRequest); | ||
} | ||
|
||
private ResponseEntity<Object> handleExceptionInternalArgs(Exception e, HttpHeaders httpHeaders, | ||
ErrorStatus errorStatus, | ||
WebRequest webRequest, | ||
Map<String, String> errorArgs) { | ||
|
||
ApiResponse<Object> body = ApiResponse.onFailure(errorStatus.getCode(), errorStatus.getMessage(), null); | ||
|
||
return super.handleExceptionInternal(e, body, httpHeaders, errorStatus.getHttpStatus(), webRequest); | ||
} | ||
|
||
|
||
private ResponseEntity<Object> handleExceptionInternalMessage(Exception e, HttpHeaders httpHeaders, | ||
WebRequest webrequest, String errorMessage) { | ||
|
||
ErrorStatus badRequestErrorStatus = ErrorStatus._BAD_REQUEST; | ||
ApiResponse<String> body = ApiResponse.onFailure(badRequestErrorStatus.getCode(), badRequestErrorStatus.getMessage(), errorMessage); | ||
|
||
return super.handleExceptionInternal(e, body, httpHeaders, badRequestErrorStatus.getHttpStatus(), webrequest); | ||
} | ||
|
||
private ResponseEntity<Object> handleExceptionInternalConstraint(Exception e, ErrorStatus errorStatus, HttpHeaders headers, WebRequest request) { | ||
ApiResponse<Object> body = ApiResponse.onFailure(errorStatus.getCode(), errorStatus.getMessage(), null); | ||
|
||
return super.handleExceptionInternal(e, body, headers, errorStatus.getHttpStatus(), request); | ||
} | ||
|
||
private ResponseEntity<Object> handleExceptionInternalFalse(Exception e, ErrorStatus errorStatus, | ||
HttpHeaders httpHeaders, HttpStatus httpStatus, | ||
WebRequest webRequest, String errorPoint) { | ||
|
||
ApiResponse<String> body = ApiResponse.onFailure(errorStatus.getCode(), errorStatus.getMessage(), errorPoint); | ||
|
||
return super.handleExceptionInternal(e, body, httpHeaders, httpStatus, webRequest); | ||
} | ||
} | ||
|
20 changes: 20 additions & 0 deletions
20
src/main/java/ussum/homepage/global/error/exception/GeneralException.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,20 @@ | ||
package ussum.homepage.global.error.exception; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import ussum.homepage.global.error.code.BaseErrorCode; | ||
import ussum.homepage.global.error.dto.ErrorReasonDto; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public class GeneralException extends RuntimeException { | ||
private BaseErrorCode baseErrorCode; | ||
|
||
public ErrorReasonDto getErrorReason() { | ||
return this.baseErrorCode.getReason(); | ||
} | ||
|
||
public ErrorReasonDto getErrorReasonHttpStatus() { | ||
return this.baseErrorCode.getReasonHttpStatus(); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/ussum/homepage/global/error/exception/InvalidValueException.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,10 @@ | ||
package ussum.homepage.global.error.exception; | ||
|
||
import ussum.homepage.global.error.code.BaseErrorCode; | ||
|
||
public class InvalidValueException extends GeneralException { | ||
private BaseErrorCode baseErrorCode; | ||
public InvalidValueException(BaseErrorCode baseErrorCode) { | ||
super(baseErrorCode); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
src/main/java/ussum/homepage/global/error/status/ErrorStatus.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,74 @@ | ||
package ussum.homepage.global.error.status; | ||
|
||
import ussum.homepage.global.error.code.BaseErrorCode; | ||
import ussum.homepage.global.error.dto.ErrorReasonDto; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public enum ErrorStatus implements BaseErrorCode { | ||
//기본(전역) 에러 | ||
_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"COMMON_500", "서버에서 요청을 처리 하는 동안 오류가 발생했습니다."), | ||
_BAD_REQUEST(HttpStatus.BAD_REQUEST,"COMMON_400", "입력 값이 잘못된 요청 입니다."), | ||
_UNAUTHORIZED(HttpStatus.UNAUTHORIZED,"COMMON_401", "인증이 필요 합니다."), | ||
_FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON_403", "금지된 요청 입니다."), | ||
|
||
//User 관련 에러 | ||
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER_001", "사용자를 찾을 수 없습니다."), | ||
|
||
//Group 관련 에러 | ||
GROUP_NOT_FOUND(HttpStatus.NOT_FOUND,"GROUP_001","그룹을 찾을 수 없습니다."), | ||
ALREADY_GROUP_EXIST(HttpStatus.NOT_FOUND,"GROUP_002","같은 code를 가진 그룹이 존재한다."), | ||
|
||
//Member 관련 에러 | ||
MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND,"MEMBER_001","멤버를 찾을 수 없습니다."), | ||
|
||
//Board 관련 에러 | ||
BOARD_NOT_FOUND(HttpStatus.NOT_FOUND,"BOARD_001","게시판을 찾을 수 없습니다."), | ||
|
||
//Post 관련 에러 | ||
POST_NOT_FOUND(HttpStatus.NOT_FOUND,"POST_001","게시글을 찾을 수 없습니다."), | ||
|
||
//ACL 관련 에러 | ||
ACL_PERMISSION_DENIED(HttpStatus.FORBIDDEN,"ACL_001","ACL에 권한이 없습니다."), | ||
INVALID_TARGET(HttpStatus.BAD_REQUEST,"ACL_002","잘못된 ACL을 입력하였습니다."), | ||
|
||
//Role 관련 에러 | ||
ROLE_PERMISSION_DENIED(HttpStatus.FORBIDDEN,"ROLE_001","필요한 Role을 가지고 있지 않습니다."), | ||
|
||
//Token 관련 에러 | ||
INVALID_TOKEN(HttpStatus.BAD_REQUEST,"TOKEN_001","토큰이 올바르지 않습니다."), | ||
|
||
//Body 에러 | ||
INVALID_BODY(HttpStatus.BAD_REQUEST, "BODY_ERROR", "Body가 올바르지 않습니다."); | ||
|
||
|
||
|
||
|
||
private final HttpStatus httpStatus; | ||
private final String code; | ||
private final String message; | ||
|
||
@Override | ||
public ErrorReasonDto getReason() { | ||
return ErrorReasonDto.builder() | ||
.isSuccess(false) | ||
.code(code) | ||
.message(message) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public ErrorReasonDto getReasonHttpStatus() { | ||
return ErrorReasonDto.builder() | ||
.isSuccess(false) | ||
.httpStatus(httpStatus) | ||
.code(code) | ||
.message(message) | ||
.build(); | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.