Skip to content

Commit

Permalink
Merge branch 'main' into feat/#310
Browse files Browse the repository at this point in the history
  • Loading branch information
splitCoding authored Aug 17, 2023
2 parents 76d87f3 + 3f3190e commit dee1937
Show file tree
Hide file tree
Showing 46 changed files with 586 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import shook.shook.auth.exception.TokenException;
Expand Down Expand Up @@ -65,9 +66,9 @@ public Claims parseClaims(final String token) {
.parseClaimsJws(token)
.getBody();
} catch (MalformedJwtException | SignatureException e) {
throw new TokenException.NotIssuedTokenException();
throw new TokenException.NotIssuedTokenException(Map.of("Token", token));
} catch (ExpiredJwtException e) {
throw new TokenException.ExpiredTokenException();
throw new TokenException.ExpiredTokenException(Map.of("Token", token));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package shook.shook.auth.exception;

import java.util.Map;
import shook.shook.globalexception.CustomException;
import shook.shook.globalexception.ErrorCode;

Expand All @@ -9,15 +10,30 @@ public AuthorizationException(final ErrorCode errorCode) {
super(errorCode);
}

public AuthorizationException(
final ErrorCode errorCode,
final Map<String, String> inputValuesByProperty
) {
super(errorCode, inputValuesByProperty);
}

public static class RefreshTokenNotFoundException extends AuthorizationException {

public RefreshTokenNotFoundException(final Map<String, String> inputValuesByProperty) {
super(ErrorCode.REFRESH_TOKEN_NOT_FOUND_EXCEPTION, inputValuesByProperty);
}

public RefreshTokenNotFoundException() {
super(ErrorCode.REFRESH_TOKEN_NOT_FOUND_EXCEPTION);
}
}

public static class AccessTokenNotFoundException extends AuthorizationException {

public AccessTokenNotFoundException(final Map<String, String> inputValuesByProperty) {
super(ErrorCode.ACCESS_TOKEN_NOT_FOUND, inputValuesByProperty);
}

public AccessTokenNotFoundException() {
super(ErrorCode.ACCESS_TOKEN_NOT_FOUND);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ public OAuthException(final ErrorCode errorCode) {
super(errorCode);
}

public static class InvalidEmailException extends OAuthException {

public InvalidEmailException() {
super(ErrorCode.INVALID_EMAIL);
}
}

public static class InvalidAccessTokenException extends OAuthException {

public InvalidAccessTokenException() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package shook.shook.auth.exception;

import java.util.Map;
import shook.shook.globalexception.CustomException;
import shook.shook.globalexception.ErrorCode;

Expand All @@ -9,17 +10,32 @@ public TokenException(final ErrorCode errorCode) {
super(errorCode);
}

public TokenException(
final ErrorCode errorCode,
final Map<String, String> inputValuesByProperty
) {
super(errorCode, inputValuesByProperty);
}

public static class NotIssuedTokenException extends TokenException {

public NotIssuedTokenException() {
super(ErrorCode.NOT_ISSUED_TOKEN);
}

public NotIssuedTokenException(final Map<String, String> inputValuesByProperty) {
super(ErrorCode.NOT_ISSUED_TOKEN, inputValuesByProperty);
}
}

public static class ExpiredTokenException extends TokenException {

public ExpiredTokenException() {
super(ErrorCode.EXPIRED_TOKEN);
}

public ExpiredTokenException(final Map<String, String> inputValuesByProperty) {
super(ErrorCode.EXPIRED_TOKEN, inputValuesByProperty);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import shook.shook.auth.application.TokenProvider;
Expand Down Expand Up @@ -33,9 +34,11 @@ public boolean preHandle(
final HttpServletRequest request,
final HttpServletResponse response,
final Object handler
) throws Exception {
) {
final String token = TokenHeaderExtractor.extractToken(request)
.orElseThrow(AuthorizationException.AccessTokenNotFoundException::new);
.orElseThrow(() -> new AuthorizationException.AccessTokenNotFoundException(
Map.of("RequestURL", request.getRequestURL().toString())
));
final Claims claims = tokenProvider.parseClaims(token);
final Long memberId = claims.get("memberId", Long.class);
final String nickname = claims.get("nickname", String.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,69 @@
package shook.shook.globalexception;

import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import org.springframework.validation.FieldError;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@ToString
@Getter
public class CustomException extends RuntimeException {

private static final String EXCEPTION_INFO_BRACKET = "{ %s }";
private static final String PROPERTY_VALUE = " Property: %s, Value: %s ";
private static final String VALUE_DELIMITER = "/";

private final int code;
private final String message;
private final Map<String, String> inputValuesByProperty;

protected CustomException(final ErrorCode errorCode) {
this(errorCode, Collections.emptyMap());
}

public CustomException(final ErrorCode errorCode) {
protected CustomException(
final ErrorCode errorCode,
final Map<String, String> inputValuesByProperty
) {
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
this.inputValuesByProperty = inputValuesByProperty;
}

public static CustomException of(
final ErrorCode errorCode,
final Map<String, String> propertyValues
) {
return new CustomException(errorCode, propertyValues);
}

public static CustomException from(final ErrorCode errorCode) {
return new CustomException(errorCode);
}

public static CustomException fromFieldError(final FieldError fieldError) {
final String inputValue = (String) fieldError.getRejectedValue();
final String errorMessage = fieldError.getDefaultMessage();
final String field = fieldError.getField();

return new CustomException(
ErrorCode.REFRESH_TOKEN_NOT_FOUND_EXCEPTION.getCode(),
errorMessage,
Map.of(field, inputValue)
);
}

public String getErrorPropertyValue() {
final String propertyWithValue = inputValuesByProperty.entrySet()
.stream()
.map(entry -> String.format(PROPERTY_VALUE, entry.getKey(), entry.getValue()))
.collect(Collectors.joining(VALUE_DELIMITER));

return String.format(EXCEPTION_INFO_BRACKET, propertyWithValue);
}
}
21 changes: 11 additions & 10 deletions backend/src/main/java/shook/shook/globalexception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,27 @@
public enum ErrorCode {

// 1000: 로그인, 인증, 인가

NOT_ISSUED_TOKEN(1000, "파싱에 실패한 토큰입니다."),
EXPIRED_TOKEN(1001, "유효기간이 만료된 토큰입니다."),
INVALID_EMAIL(1002, "유효하지 않은 이메일입니다."),
INVALID_AUTHORIZATION_CODE(1003, "올바르지 않은 authorization code 입니다."),
INVALID_ACCESS_TOKEN(1004, "잘못된 구글 accessToken 입니다."),
GOOGLE_SERVER_EXCEPTION(1005, "구글 서버에서 오류가 발생했습니다."),
REFRESH_TOKEN_NOT_FOUND_EXCEPTION(1006, "accessToken 을 재발급하기 위해서는 refreshToken 이 필요합니다."),
ACCESS_TOKEN_NOT_FOUND(1007, "accessToken이 필요합니다."),

// 2000: 킬링파트 - 좋아요, 댓글

EMPTY_KILLING_PART_COMMENT(2001, "킬링파트 댓글은 비어있을 수 없습니다."),
TOO_LONG_KILLING_PART_COMMENT(2002, "킬링파트 댓글 길이는 최대 200 글자여야 합니다."),
KILLING_PART_COMMENT_FOR_OTHER_PART(2003, "해당 댓글은 다른 킬링파트의 댓글입니다."),
DUPLICATE_COMMENT_EXIST(2004, "동일한 킬링파트 댓글이 존재합니다."),

KILLING_PART_NOT_EXIST(2005, "킬링파트가 존재하지 않습니다."),

KILLING_PART_SONG_NOT_UPDATABLE(2006, "이미 다른 노래의 킬링파트에 속해있습니다."),
SONG_MAX_KILLING_PART_EXCEEDED(2007, "노래의 킬링파트는 3개를 초과할 수 없습니다."),

LIKE_FOR_OTHER_KILLING_PART(2008, "다른 킬링파트에 대한 좋아요입니다."),
EMPTY_LIKE_EXCEPTION(2009, "비어있는 좋아요를 킬링파트에 등록할 수 없습니다."),

EMPTY_LIKE_EXCEPTION(2009, "비어있는 좋아요를 킬링파트에 등록할 수 없습니다."),
KILLING_PARTS_OUT_OF_SIZE(2010, "킬링파트는 3개여야 합니다."),
EMPTY_KILLING_PARTS(2011, "노래의 킬링파트는 비어있을 수 없습니다."),

Expand All @@ -52,15 +51,15 @@ public enum ErrorCode {
VOTING_PART_END_OVER_SONG_LENGTH(4003, "파트의 끝 초는 노래 길이를 초과할 수 없습니다."),
INVALID_VOTING_PART_LENGTH(4004, "파트의 길이는 5, 10, 15초 중 하나여야합니다."),
VOTING_PART_DUPLICATE_START_AND_LENGTH_EXCEPTION(4005,
"한 노래에 동일한 파트를 두 개 이상 등록할 수 없습니다."), //500

"한 노래에 동일한 파트를 두 개 이상 등록할 수 없습니다."),
VOTING_SONG_PART_NOT_EXIST(4006, "투표 대상 파트가 존재하지 않습니다."),

VOTING_SONG_PART_FOR_OTHER_SONG(4007, "해당 파트는 다른 노래의 파트입니다."),
VOTING_SONG_NOT_EXIST(4008, "존재하지 않는 투표 노래입니다."),
VOTE_FOR_OTHER_PART(4009, "해당 투표는 다른 파트에 대한 투표입니다."),
DUPLICATE_VOTE_EXIST(4010, "중복된 투표입니다."),

// 5000: 사용자

EMPTY_EMAIL(5001, "이메일은 비어있을 수 없습니다."),
TOO_LONG_EMAIL(5002, "이메일은 100자를 초과할 수 없습니다."),
INVALID_EMAIL_FORM(5003, "이메일 형식에 맞지 않습니다."),
Expand All @@ -69,8 +68,10 @@ public enum ErrorCode {
EXIST_MEMBER(5006, "이미 회원가입 된 멤버입니다."),
MEMBER_NOT_EXIST(5007, "존재하지 않는 멤버입니다."),

REQUEST_BODY_VALIDATION_FAIL(10001, "필드명: %s, 오류 메세지: %s"),
WRONG_REQUEST_URL(10002, "URL의 pathVariable 은 비어있을 수 없습니다.");
REQUEST_BODY_VALIDATION_FAIL(10001, ""),
WRONG_REQUEST_URL(10002, "URL의 pathVariable 은 비어있을 수 없습니다."),

INTERNAL_SERVER_ERROR(10003, "알 수 없는 서버 오류가 발생했습니다. 관리자에게 문의해주세요.");

private final int code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.validation.FieldError;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
Expand All @@ -15,13 +14,4 @@ public class ErrorResponse {
public static ErrorResponse from(final CustomException customException) {
return new ErrorResponse(customException.getCode(), customException.getMessage());
}

public static ErrorResponse fromMethodArgumentException(
final CustomException exception, final FieldError fieldError
) {
final String field = fieldError.getField();
final String message = fieldError.getDefaultMessage();
return new ErrorResponse(exception.getCode(),
String.format(exception.getMessage(), field, message));
}
}
Loading

0 comments on commit dee1937

Please sign in to comment.