Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

[BE] refactor: 예외 메시지 포맷 수정 #263

Merged
merged 14 commits into from
Aug 15, 2023

Conversation

HubCreator
Copy link
Member

@HubCreator HubCreator commented Aug 14, 2023

🛠️ Issue

✅ Tasks

  • 예외 메시지 형식 수정
  • 예외 메시지 내용 수정

⏰ Time Difference

  • 2 -> 1

📝 Note

JWT쪽도 머지 되면 그쪽에 존재하는 예외 메시지들도 함께 수정하겠습니다.

@HubCreator HubCreator self-assigned this Aug 14, 2023
@HubCreator HubCreator changed the title refactor: 예외 메시지 포맷 수정 [BE] refactor: 예외 메시지 포맷 수정 Aug 14, 2023
jeonjeunghoon and others added 9 commits August 14, 2023 17:59
* feat: 글 휴지통으로 이동, 글 삭제 api 구현

* chore: `DeleteIcon` -> `TrashCanIcon`

* feat: `DeleteButton` 컴포넌트 구현

* test: trash api handler 작성

* feat: `handlers` 에 `trashHandlers` 추가

* feat: `WritingList` 에 휴지통 컴포넌트 추가

* feat: 글 삭제 시 `confirm` 추가

* refactor: `useDeleteWritings` 훅 분리

* feat: `useDeleteWritings` 쿼리 캐시 동기화 메서드 추가

* chore: `flex: 1` 제거
* feat: 글 제목 변경 API 작성

* feat: 글 제목 변경 API mocking

* style: `Input` size large 스타일 변경

* refactor: `writingPage` path에 categoryId도 포함하도록 수정

* feat: 글 제목 변경하는 기능 구현

* feat: 파일 업로드 용량 제한 설정

* fix: map key 에러 수정

* refactor: `Input` large 스타일 기존 스타일로 다시 변경

* refactor: `WritingViewer`에서 `WritingTitle` 분리
* refactor: 기존 `Block Entity` 삭제 및 `Content` -> `Block`으로 변경

* refactor: `setter` 제거 -> 생성자에서 `Writing` 주입
* chore: `cypress` 설치 및 설정파일 추가

* fix: cypress sourceMap 에러로 인해 `tsconfig` 설정에서 sourceMap 제거

* chore: `eslint-plugin-cypress` 설치

* test: `cypress` config `baseUrl` 옵션 추가

* test: `@testing-library/cypress` 설치 및 환경설정

* test: 글 가져오기 모달 창 열기 테스트 추가

* feat: 카테고리 추가 input에 `aria-label` 추가

* test: 카테고리 추가 테스트 추가

* chore: `cypress-real-events` 설치

실제 마우스 호버링 동작 재현을 위해 설치
호버링 말고도 많은 동작을 재현할 수 있음

* feat: 카테고리 이름 수정 입력 input `aria-label` 추가

* test: 카테고리 이름 수정 테스트 추가

* test: 카테고리 삭제 테스트 추가

* chore: 파일 업로드 테스트를 위한 `cypress-file-upload` 라이브러리 설치

* feat: 파일업로드 모달에 있는 파일 업로드 존 `aria-label` 추가

* test: 드래그 앤 드롭으로 마크다운 파일을 업로드하는 기능 테스트 추가

* test: 기본 카테고리에서 업로드한 글을 확인하는 테스트 추가

* refactor: test 성격에 맞게 describle 나누기

* test: cypress test CI 스크립트 추가

* refactor: conflict 해결

* chore: cypress test CI 스크립트 문법 수정

* chore: default run working-directory 수정

${{ vars.FE_DIRECTORY }} 인식 안되는 문제..

* chore: actions 개행 수정

* chore: e2e test CI `paths` 추가

* Update fe-test-e2e.yml

if: contains(github.event.pull_request.labels.*.name, 'frontend') 제거

* Update fe-test-e2e.yml

* chore: 서버 시작 후 테스트 하는 스크립트 추가

* chore: cypress 테스트 비디오 gitignore에 추가

* refactor: aria-label `파일 업로드 존` -> `파일 업로드`
* feat: `KakaoLoginIcon` 추가

* feat: `oauthRedirectURL`, `oauthLoginURL` 추가

* test: login handler 작성

* feat: `Kakao` 컴포넌트 구현

* feat: login api 구현

* feat: `goHomePage` 함수 구현

* refactor: `PostOauthLogin` 타입 수정

* feat: `OauthPage` 구현

* refactor: `PostOauthLogin` -> `PostOauthLoginRequest`

* feat: IntroducePage 컴포넌트 구현

* fix: api 요청 오류 해결

* chore: import 순서 수정

* feat: oauth error 처리 추가

* chore: 주석 삭제, `Kakao` 이름 수정
* feat: jwt 의존성 추가

Co-authored-by: HubCreator <[email protected]>

* feat: Jwt 토큰 발급 기능 구현

Co-authored-by: HubCreator <[email protected]>

* feat: `Token` Entity 생성

Co-authored-by: HubCreator <[email protected]>

* refactor: `member` 정적 팩토리 메서드 입력값 수정

Co-authored-by: HubCreator <[email protected]>

* feat: JWT 정책 추가

Co-authored-by: HubCreator <[email protected]>

* feat: 인터셉터 초안

Co-authored-by: HubCreator <[email protected]>

* refactor: 사용하지 않는 클래스 삭제

Co-authored-by: HubCreator <[email protected]>

* feat: token을 반환하는 Extractor기능 구현

Co-authored-by: HubCreator <[email protected]>

* feat: token의 대한 CustomException 정의

Co-authored-by: HubCreator <[email protected]>

* feat: 인증에 사용되는 커스텀 어노테이션 정의

Co-authored-by: HubCreator <[email protected]>

* feat: access와 refresh 토큰 Interceptor 기능 구현

Co-authored-by: HubCreator <[email protected]>

* feat: refreshToken의 유효성 검사 로직 기능 구현

Co-authored-by: HubCreator <[email protected]>

* feat: 토큰 검증 후 AccessToken 발급 기능 구현

Co-authored-by: HubCreator <[email protected]>

* refactor: token의 payload key값 변경

Co-authored-by: HubCreator <[email protected]>

* feat: accessToken Resolver기능 구현

Co-authored-by: HubCreator <[email protected]>

* refactor: 패키지 변경 및 DTO생성

Co-authored-by: HubCreator <[email protected]>

* refactor: test 코드 수정

Co-authored-by: HubCreator <[email protected]>

* feat: 인가 어노테이션 적용

Co-authored-by: HubCreator <[email protected]>

* feat: token의 대한 환경변수 추가

Co-authored-by: HubCreator <[email protected]>

* refactor :환경변수 추가 및 개행 제거

Co-authored-by: HubCreator <[email protected]>

* refactor :Response타입 변경

Co-authored-by: HubCreator <[email protected]>

* refactor :docker 설정 및 환경변수 수정

* refactor :재발급 기준 변경

* refactor :config 결합 및 Interceptor범위 수정

* refactor :네이밍 수정

* refactor :interceptor범위 수정

* refactor :token을 return방식 수정

* refactor :사용하지 않는 어노테이션 삭제

* refactor :사용하지 않는 파라미터 삭제

* refactor :Cookie 유효시간 생성자 주입 적용

* refactor :Path범위 수정

* refactor :중복 되는 로직 메서드 분리

* refactor :접근제어자 변경

* refactor :long -> int 변경

* refactor :에러 메시지 오타 수정

* refactor :개행 제거

* refactor :불필요한 if문 제거

---------

Co-authored-by: HubCreator <[email protected]>
Co-authored-by: echo724 <[email protected]>
# Conflicts:
#	backend/src/main/java/org/donggle/backend/application/service/AuthService.java
#	backend/src/main/java/org/donggle/backend/auth/JwtTokenProvider.java
#	backend/src/main/java/org/donggle/backend/auth/exception/EmptyAuthorizationHeaderException.java
#	backend/src/main/java/org/donggle/backend/auth/presentation/AuthInterceptor.java
#	backend/src/main/java/org/donggle/backend/auth/presentation/RefreshTokenAuthInterceptor.java
#	backend/src/main/java/org/donggle/backend/auth/support/AuthorizationExtractor.java
Copy link
Collaborator

@ezzanzzan ezzanzzan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다 !! 🙇‍♀️


public class EmptyAuthorizationHeaderException extends AuthenticationException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuthorizationHeaderNotFoundException 은 어떨까요 !?


import org.donggle.backend.exception.authentication.AuthenticationException;

public class InvalidRefreshTokenException extends AuthenticationException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유효하지 않은 RefreshToken 이라는게 만료되었다는 건가요 !?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 두 가지 상황에서 사용되고 있네요! Member로부터 찾은 RefreshToken이 다르거나, RefreshToken 자체의 만료 기간이 지났을 때에 InvalidRefreshTokenException을 뱉고 있어요.

두 가지 상황을 분리하여 예외를 던지는 것이 좋을까요?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Member로부터 찾은 RefreshToken이 다를 때가 만료기간이 지났거나, 새로운 토큰이 발급되었을 때 발생하는 상황이 맞을까요 ?!

그렇다면 ExpiredTokenException과 같이 ExpiredRefreshTokenException을 던져줘도 괜찮지 않을까 생각했습니다 !

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Member로부터 찾은 RefreshToken이 다를 때가 만료기간이 지났거나, 새로운 토큰이 발급되었을 때 발생하는 상황이 맞을까요 ?!

맞아요! ExpiredRefreshTokenException을 던지도록 상황을 구분하여 수정해봤습니다!


import org.donggle.backend.exception.business.BusinessException;

public class InvalidAuthorizationHeaderTypeException extends BusinessException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 예외는 BusinessException인 이유가 있나요 ?!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흠.. 착각했네요 수정하겠습니다~!

import org.donggle.backend.exception.business.BusinessException;
import org.springframework.http.HttpStatus;

public class RefreshTokenNotFoundException extends BusinessException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 예외도 BusinessException인데 AuthenticationException과 어떤 기준으로 나눠서 사용하신건지 궁금합니다 !

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ezzanzzan
으아 여기도 착각한 것 같아요! 사용자가 특정 uri에 대해 요청했을 때 자원이 없는게 아니라, 그냥 요청을 했는데 해당 멤버가 가지고 있는 토큰이 없기 때문에 NotFoundException 보다는 AuthenticateException을 던지도록 하는 것이 좋겠죠..?!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

옹 동의합니다 ! 멤버가 가지고 있는 토큰이 없는건 인증의 문제..이지 않을까요 !?!? 🥺🥹

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 ㅋㅋㅋ 그런 것 같아요! 인증쪽 예외로 수정하였어요


public abstract String getHint();

public abstract int getErrorCode();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public abstract int getErrorCode();
public final int getErrorCode() {
return HttpStatus.BAD_REQUEST.value();
}

는 어떨까요 ?!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BusinessException은 예외로 해당 메서드를 abstract로 두어 하위에서 재정의하도록 하였는데요,
다른 예외들과는 달리 추후에 우리가 비즈니스적으로 예외 코드를 프론트와 상의해서 줘야할 상황이 생길 것 같아서 이처럼 구현했습니다.
괜찮은 생각일까요?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BusinessException을 상속받는 클래스들을 살펴보았는데 다 BadRequst를 ErrorCode로 가지고 있기에 통일해줘도 괜찮지않을까 생각했습니다 ! 헙크의 의견도 동의합니다 좋은데요 !?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! 언젠가 커스텀 예외 코드를 사용할 일이 생기길!!

public class InvalidBasicCategoryException extends BusinessException {
private static final String MESSAGE = "기본 카테고리는 변경이 불가합니다.";
private static final String MESSAGE = "잘못된 요청입니다. 카테고리 이름은 '기본'이 될 수 없습니다.";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 예외가 기본 카테고리에 대한 이름 변경(수정), 삭제, 이동 등에 사용되는 것 같아요 !
기존에 쓰이던 메세지가 더 나을 것 같습니다 !

return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse);
final ErrorWrapper errorWrapper = new ErrorWrapper(
ErrorContent.of(e.getMessage(), e.getHint(), e.getErrorCode())

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개행빼주세유

Copy link
Collaborator

@echo724 echo724 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정하느라 고생좀 했을 것 같습니다.. 아주 깔끔하네요!


@Override
public int getErrorCode() {
return 403;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

401은 클라이언트의 인증 실패를 나타내는 반면, 403은 클라이언트가 리소스에 대한 접근 권한이 없는 것을 의미한다고 합니다! 이 경우 클라이언트에서 헤더 값을 잘못 넣어준것이니 401이 맞지 않을까 싶네요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 수정했습니다!

public TokenResponse reissueAccessTokenAndRefreshToken(final Long memberId) {
final Member member = memberRepository.findById(memberId).
orElseThrow(NoSuchTokenException::new);

orElseThrow(RefreshTokenNotFoundException::new);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 MemberNotFoundException이 맞지 않을까 생각합니다. memberId로 memberRepository에서 Member를 찾아오는 걸로 보이네요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어라.. 그렇네요?! 에코 말 듣고보니까 전형적인 MemberNotFoundException인데 시야가 좁아졌었나봅니다 ㅋㅋㅋ 땡큐 에코오

package org.donggle.backend.ui.common;

public record ErrorContent(String message, String hint, int code){
public static ErrorContent of(final String message, final String hint, final int code) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

힌트 다시 봐도 좋은 표현인 것 같네요! 지니어스헙 인정합니다~

@@ -25,33 +25,50 @@
@RestControllerAdvice
public class GlobalExceptionHandler {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어마어마한 수정... 고생했어요

@echo724 echo724 added 🛠️ refactor 코드 리팩터링, 개선 🕋 backend 백엔드 작업 labels Aug 15, 2023
Copy link
Collaborator

@ingpyo ingpyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와우,,,, 너무 수고했어요,,

@HubCreator HubCreator merged commit 55939ce into develop Aug 15, 2023
@HubCreator HubCreator deleted the feature/modify-exception-message-260 branch August 15, 2023 03:34
echo724 pushed a commit that referenced this pull request Aug 18, 2023
* feat: 예외 메시지 포맷 수정

* refactor: 에  키워드 추가

* refactor: `auth` 패키지 내의 예외 메시지 포맷 수정

* refactor: merge 후 필요 없는 클래스 삭제

* refactor: 피드백 반영

* refactor: `RefreshTokenNotFoundException`을 `MemberNotFoundException`으로 수정

* refactor: `ExpiredAccessTokenException`과 `ExpiredRefreshTokenException`을 분리
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🕋 backend 백엔드 작업 🛠️ refactor 코드 리팩터링, 개선
Projects
None yet
Development

Successfully merging this pull request may close these issues.

예외 메시지 포맷 수정
7 participants