Skip to content

Commit

Permalink
[Feat]: 에러응답 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
bayy1216 committed May 30, 2024
1 parent dde83e1 commit 0ba86d1
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.haedal.zzansuni.global.api;

import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.haedal.zzansuni.core.api.ApiResponse;
import org.haedal.zzansuni.core.api.ErrorCode;
import org.haedal.zzansuni.global.exception.UnauthorizedException;
import org.slf4j.MDC;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.NoSuchElementException;

@RestControllerAdvice
@Slf4j
public class ApiControllerAdvice {



/**
* http status: 400 AND result: FAIL
* 잘못된 요청
*/
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> illegalArgumentException(IllegalArgumentException e) {
return ApiResponse.fail(ErrorCode.COMMON_INVALID_PARAMETER);
}

/**
* http status: 400 AND result: FAIL
* 잘못된 요청
*/
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> illegalStateException(IllegalStateException e) {
return ApiResponse.fail(ErrorCode.COMMON_INVALID_PARAMETER);
}

/**
* http status: 404 AND result: FAIL
* 존재하지 않는 엔티티
*/
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiResponse<Void> noSuchElementException(NoSuchElementException e) {
return ApiResponse.fail(ErrorCode.COMMON_ENTITY_NOT_FOUND);
}


/**
* http status: 401 AND result: FAIL
* 인증 실패
*/
@ExceptionHandler
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public ApiResponse<Void> onUnauthorizedException(UnauthorizedException e) {
return ApiResponse.fail("UNAUTHORIZED", e.getMessage());
}



/**
* http status: 500 AND result: FAIL
* 시스템 예외 상황. 집중 모니터링 대상
*/
@ExceptionHandler
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiResponse<Void> onException(Exception e) {
String eventId = MDC.get(CommonHttpRequestInterceptor.HEADER_REQUEST_UUID_KEY);
log.error("eventId = {} ", eventId, e);
return ApiResponse.fail(ErrorCode.COMMON_SYSTEM_ERROR);
}




}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.haedal.zzansuni.global.exception;

public class UnauthorizedException extends RuntimeException{
public UnauthorizedException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.haedal.zzansuni.global.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.haedal.zzansuni.global.exception.UnauthorizedException;
import org.haedal.zzansuni.global.security.Role;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -60,7 +60,7 @@ public boolean validateToken(String rawToken) {
public String reissueAccessToken(JwtToken.ValidToken refreshToken) {
Claims claims = extractClaims(refreshToken.getValue());
if (claims.get(IS_ACCESS_TOKEN, Boolean.class)) {
throw new JwtException("RefreshToken이 유효하지 않습니다.");
throw new UnauthorizedException("RefreshToken이 유효하지 않습니다.");
}
JwtUser jwtUser = claimsToJwtUser(claims);
return generateToken(jwtUser, true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.haedal.zzansuni.global.security;

import io.jsonwebtoken.JwtException;
import lombok.RequiredArgsConstructor;
import org.haedal.zzansuni.global.exception.UnauthorizedException;
import org.haedal.zzansuni.global.jwt.JwtToken;
import org.haedal.zzansuni.global.jwt.JwtUser;
import org.haedal.zzansuni.global.jwt.JwtUtils;
Expand Down Expand Up @@ -32,7 +32,7 @@ public Authentication authenticate(Authentication authentication) throws Authent

// 토큰을 검증하는 단계
if(!jwtUtils.validateToken(token)){
throw new JwtException("유효하지 않은 토큰입니다.");
throw new UnauthorizedException("유효하지 않은 토큰입니다.");
}
JwtUser jwtUser = jwtUtils.getJwtUser(JwtToken.ValidToken.of(token));
Set<SimpleGrantedAuthority> authorities = Set.of(new SimpleGrantedAuthority(jwtUser.getRole().name()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.haedal.zzansuni.core.api.ApiResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -75,20 +76,20 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
*/
http.exceptionHandling((exception) -> exception
.authenticationEntryPoint((request, response, authException) -> {
// var errorResponse = ErrorResponse.of("권한이 없습니다.");
// var json = objectMapper.writeValueAsString(errorResponse);
var errorResponse = ApiResponse.fail("UNAUTHORIZED", "인증이 필요합니다.");
var json = objectMapper.writeValueAsString(errorResponse);
response.setStatus(401);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
// response.getWriter().write(json);
response.getWriter().write(json);
response.getWriter().flush();
})
.accessDeniedHandler((request, response, accessDeniedException) -> {
// var errorResponse = ErrorResponse.of("권한이 없습니다.");
// var json = objectMapper.writeValueAsString(errorResponse);
var errorResponse = ApiResponse.fail("ACCESS_DENIED", "권한이 없습니다.");
var json = objectMapper.writeValueAsString(errorResponse);

response.setStatus(403);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
// response.getWriter().write(json);
response.getWriter().write(json);
response.getWriter().flush();
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.haedal.zzansuni.domain.user.UserReader;
import org.springframework.stereotype.Component;

import java.util.NoSuchElementException;
import java.util.Optional;

@Component
Expand All @@ -15,7 +16,7 @@ public class UserReaderImpl implements UserReader {

@Override
public User getById(Long id) {
return userRepository.findById(id).orElseThrow(EntityNotFoundException::new);
return userRepository.findById(id).orElseThrow(NoSuchElementException::new);
}

@Override
Expand Down

0 comments on commit 0ba86d1

Please sign in to comment.