-
Notifications
You must be signed in to change notification settings - Fork 0
[REFACTOR] 결제 코드 리팩토링 #15
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
Changes from all commits
9df150b
898a3da
03fc848
b0ac8f6
97f10a7
002d32f
6edc07e
85ab7a7
98a0630
83ca1f8
96826a7
713e009
bbc84df
2f054da
b935861
e814357
e3dab16
2f29348
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| --- | ||
| name: Bug report | ||
| about: Create a report to help us improve | ||
| title: '[FIX] ' | ||
| labels: '' | ||
| assignees: '' | ||
|
|
||
| --- | ||
|
|
||
| # 버그 내용 | ||
|
|
||
| # 스크린샷 | ||
|
|
||
| # 참고 사항 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| name: Feat request | ||
| about: Suggest an idea for this project | ||
| title: '[FEAT] ' | ||
| labels: '' | ||
| assignees: '' | ||
|
|
||
| --- | ||
|
|
||
| # 투두 리스트 | ||
|
|
||
| # 참고 사항 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| name: Refactor request | ||
| about: Suggest an idea for this project | ||
| title: '[REFACTOR] ' | ||
| labels: '' | ||
| assignees: '' | ||
|
|
||
| --- | ||
|
|
||
| # 투두 리스트 | ||
|
|
||
| # 참고 사항 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| closed # | ||
|
|
||
| # 작업 내용 | ||
|
|
||
| # 참고 사항 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,3 +35,4 @@ out/ | |
|
|
||
| ### VS Code ### | ||
| .vscode/ | ||
| .claude | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package com.samhap.kokomen.global.exception; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public enum ApiErrorMessage { | ||
|
|
||
| AUTHENTICATION_ANNOTATION_REQUIRED("MemberAuth 파라미터는 @Authentication 어노테이션이 있어야 합니다."), | ||
| LOGIN_REQUIRED("로그인이 필요합니다"), | ||
| MEMBER_ID_NOT_IN_SESSION("세션에 MEMBER_ID가 없습니다."), | ||
| INVALID_REQUEST("잘못된 요청입니다."), | ||
| MISSING_REQUEST_PARAMETER("필수 요청 파라미터가 누락되었습니다."), | ||
| INVALID_REQUEST_FORMAT("잘못된 요청 형식입니다. JSON 형식을 확인해주세요."), | ||
| JSON_PARSE_ERROR("JSON 파싱 오류: 유효하지 않은 값이 전달되었습니다."), | ||
| INTERNAL_SERVER_ERROR("서버에 문제가 발생하였습니다."); | ||
|
|
||
| private final String message; | ||
|
|
||
| ApiErrorMessage(String message) { | ||
| this.message = message; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |||||||||||||||||||||||||||||||||||||||||
| import com.fasterxml.jackson.databind.exc.InvalidFormatException; | ||||||||||||||||||||||||||||||||||||||||||
| import com.samhap.kokomen.global.dto.ErrorResponse; | ||||||||||||||||||||||||||||||||||||||||||
| import lombok.extern.slf4j.Slf4j; | ||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.context.support.DefaultMessageSourceResolvable; | ||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.http.HttpStatus; | ||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.http.ResponseEntity; | ||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.http.converter.HttpMessageNotReadableException; | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -11,7 +12,6 @@ | |||||||||||||||||||||||||||||||||||||||||
| import org.springframework.web.bind.annotation.ExceptionHandler; | ||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.web.bind.annotation.RestControllerAdvice; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // TODO: HttpMessageNotReadableException 예외 처리 추가 | ||||||||||||||||||||||||||||||||||||||||||
| @Slf4j | ||||||||||||||||||||||||||||||||||||||||||
| @RestControllerAdvice | ||||||||||||||||||||||||||||||||||||||||||
| public class GlobalExceptionHandler { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -25,12 +25,12 @@ public ResponseEntity<ErrorResponse> handleKokomenException(KokomenException e) | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @ExceptionHandler(MethodArgumentNotValidException.class) | ||||||||||||||||||||||||||||||||||||||||||
| public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { | ||||||||||||||||||||||||||||||||||||||||||
| String defaultErrorMessageForUser = "잘못된 요청입니다."; | ||||||||||||||||||||||||||||||||||||||||||
| String defaultErrorMessageForUser = ApiErrorMessage.INVALID_REQUEST.getMessage(); | ||||||||||||||||||||||||||||||||||||||||||
| String message = e.getBindingResult() | ||||||||||||||||||||||||||||||||||||||||||
| .getFieldErrors() | ||||||||||||||||||||||||||||||||||||||||||
| .stream() | ||||||||||||||||||||||||||||||||||||||||||
| .findFirst() | ||||||||||||||||||||||||||||||||||||||||||
| .map(error -> error.getDefaultMessage()) | ||||||||||||||||||||||||||||||||||||||||||
| .map(DefaultMessageSourceResolvable::getDefaultMessage) | ||||||||||||||||||||||||||||||||||||||||||
| .orElse(defaultErrorMessageForUser); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (message.equals(defaultErrorMessageForUser)) { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -44,35 +44,33 @@ public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(Metho | |||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @ExceptionHandler(MissingServletRequestParameterException.class) | ||||||||||||||||||||||||||||||||||||||||||
| public ResponseEntity<ErrorResponse> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) { | ||||||||||||||||||||||||||||||||||||||||||
| String message = "필수 요청 파라미터 '" + e.getParameterName() + "'가 누락되었습니다."; | ||||||||||||||||||||||||||||||||||||||||||
| log.warn("MissingServletRequestParameterException :: message: {}", message); | ||||||||||||||||||||||||||||||||||||||||||
| public ResponseEntity<ErrorResponse> handleMissingServletRequestParameterException( | ||||||||||||||||||||||||||||||||||||||||||
| MissingServletRequestParameterException e) { | ||||||||||||||||||||||||||||||||||||||||||
| log.warn("MissingServletRequestParameterException :: parameterName: {}", e.getParameterName()); | ||||||||||||||||||||||||||||||||||||||||||
| return ResponseEntity.status(HttpStatus.BAD_REQUEST) | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse(message)); | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse(ApiErrorMessage.MISSING_REQUEST_PARAMETER.getMessage())); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @ExceptionHandler(HttpMessageNotReadableException.class) | ||||||||||||||||||||||||||||||||||||||||||
| public ResponseEntity<ErrorResponse> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { | ||||||||||||||||||||||||||||||||||||||||||
| String message = "잘못된 요청 형식입니다. JSON 형식을 확인해주세요."; | ||||||||||||||||||||||||||||||||||||||||||
| if (e.getCause() instanceof InvalidFormatException invalidFormatException) { | ||||||||||||||||||||||||||||||||||||||||||
| String fieldName = invalidFormatException.getPath().get(0).getFieldName(); | ||||||||||||||||||||||||||||||||||||||||||
| String invalidValue = String.valueOf(invalidFormatException.getValue()); | ||||||||||||||||||||||||||||||||||||||||||
| message = String.format( | ||||||||||||||||||||||||||||||||||||||||||
| "JSON 파싱 오류: '%s' 필드에 유효하지 않은 값이 전달되었습니다. (전달된 값: '%s')", | ||||||||||||||||||||||||||||||||||||||||||
| fieldName, | ||||||||||||||||||||||||||||||||||||||||||
| invalidValue | ||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||
| log.warn("HttpMessageNotReadableException :: fieldName: {}, invalidValue: {}", fieldName, invalidValue); | ||||||||||||||||||||||||||||||||||||||||||
| return ResponseEntity.status(HttpStatus.BAD_REQUEST) | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse(ApiErrorMessage.JSON_PARSE_ERROR.getMessage())); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
56
to
62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
이전 구현처럼 어떤 필드에서 어떤 값 때문에 오류가 발생했는지에 대한 구체적인 정보를 포함하여 응답하는 것을 고려해 보세요. 민감한 정보를 노출하지 않는 선에서, 개발자에게 유용한 정보를 제공하는 것이 좋습니다. 예를 들어, 다음과 같이 상세 메시지를 생성하여 반환할 수 있습니다.
Suggested change
Comment on lines
56
to
62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🛡️ 방어 코드 제안 if (e.getCause() instanceof InvalidFormatException invalidFormatException) {
- String fieldName = invalidFormatException.getPath().get(0).getFieldName();
- String invalidValue = String.valueOf(invalidFormatException.getValue());
- log.warn("HttpMessageNotReadableException :: fieldName: {}, invalidValue: {}", fieldName, invalidValue);
+ var path = invalidFormatException.getPath();
+ if (!path.isEmpty()) {
+ String fieldName = path.get(0).getFieldName();
+ String invalidValue = String.valueOf(invalidFormatException.getValue());
+ log.warn("HttpMessageNotReadableException :: fieldName: {}, invalidValue: {}", fieldName, invalidValue);
+ } else {
+ log.warn("HttpMessageNotReadableException :: invalidValue: {}", invalidFormatException.getValue());
+ }
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse(ApiErrorMessage.JSON_PARSE_ERROR.getMessage()));
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| log.warn("HttpMessageNotReadableException :: message: {}", message); | ||||||||||||||||||||||||||||||||||||||||||
| log.warn("HttpMessageNotReadableException :: message: {}", e.getMessage()); | ||||||||||||||||||||||||||||||||||||||||||
| return ResponseEntity.status(HttpStatus.BAD_REQUEST) | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse(message)); | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse(ApiErrorMessage.INVALID_REQUEST_FORMAT.getMessage())); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @ExceptionHandler(Exception.class) | ||||||||||||||||||||||||||||||||||||||||||
| public ResponseEntity<ErrorResponse> handleException(Exception e) { | ||||||||||||||||||||||||||||||||||||||||||
| log.error("Exception :: status: {}, message: {}, stackTrace: ", HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage(), e); | ||||||||||||||||||||||||||||||||||||||||||
| log.error("Exception :: status: {}, message: {}, stackTrace: ", HttpStatus.INTERNAL_SERVER_ERROR, | ||||||||||||||||||||||||||||||||||||||||||
| e.getMessage(), e); | ||||||||||||||||||||||||||||||||||||||||||
| return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse("서버에 문제가 발생하였습니다.")); | ||||||||||||||||||||||||||||||||||||||||||
| .body(new ErrorResponse(ApiErrorMessage.INTERNAL_SERVER_ERROR.getMessage())); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.samhap.kokomen.global.exception; | ||
|
|
||
| public class InternalServerErrorException extends KokomenException { | ||
|
|
||
| public InternalServerErrorException(String message) { | ||
| super(message, 500); | ||
| } | ||
|
|
||
| public InternalServerErrorException(String message, Throwable cause) { | ||
| super(message, cause, 500); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.samhap.kokomen.global.exception; | ||
|
|
||
| public class NotFoundException extends KokomenException { | ||
|
|
||
| public NotFoundException(String message) { | ||
| super(message, 404); | ||
| } | ||
| } |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOGIN_REQUIRED메시지에 마침표(.) 누락.다른 메시지들은 모두 마침표로 끝나지만,
LOGIN_REQUIRED("로그인이 필요합니다")만 마침표가 없습니다.✏️ 수정 제안
📝 Committable suggestion
🤖 Prompt for AI Agents