Skip to content

Commit

Permalink
Merge pull request #173 from YAPP-19th/feature/#172-error-refactor
Browse files Browse the repository at this point in the history
Feature/#172 error refactor
  • Loading branch information
kihwankim authored Jan 31, 2022
2 parents ce8a0e2 + d35591a commit 9fe22fa
Show file tree
Hide file tree
Showing 36 changed files with 215 additions and 382 deletions.
4 changes: 2 additions & 2 deletions module-api/src/docs/asciidoc/food/post/fail/badRequest.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ endif::[]

====
IMPORTANT: REQUEST
include::{snippets}/foods/post/fail/badRequest/http-request.adoc[]
include::{snippets}/food/post/fail/badRequest/http-request.adoc[]
====

====
IMPORTANT: RESPONSE
include::{snippets}/foods/post/fail/badRequest/http-response.adoc[]
include::{snippets}/food/post/fail/badRequest/http-response.adoc[]
====
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ endif::[]

====
IMPORTANT: REQUEST
include::{snippets}/foods/post/fail/categoryNotFound/http-request.adoc[]
include::{snippets}/food/post/fail/categoryNotFound/http-request.adoc[]
====

====
IMPORTANT: RESPONSE
include::{snippets}/foods/post/fail/categoryNotFound/http-response.adoc[]
include::{snippets}/food/post/fail/categoryNotFound/http-response.adoc[]
====
15 changes: 13 additions & 2 deletions module-api/src/docs/asciidoc/food/post/fail/invalidOperation.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,21 @@ endif::[]

====
IMPORTANT: REQUEST
include::{snippets}/foods/post/fail/invalidOperationException/http-request.adoc[]
include::{snippets}/food/post/fail/invalidOperation1/http-request.adoc[]
====

====
IMPORTANT: RESPONSE
include::{snippets}/foods/post/fail/invalidOperationException/http-response.adoc[]
include::{snippets}/food/post/fail/invalidOperation1/http-response.adoc[]
====


====
IMPORTANT: REQUEST
include::{snippets}/food/post/fail/invalidOperation2/http-request.adoc[]
====

====
IMPORTANT: RESPONSE
include::{snippets}/food/post/fail/invalidOperation2/http-response.adoc[]
====
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.yapp.sharefood.auth.advice;

import com.yapp.sharefood.common.error.ErrorResponse;
import com.yapp.sharefood.common.exception.ForbiddenException;
import com.yapp.sharefood.external.exception.BadGatewayException;
import com.yapp.sharefood.oauth.exception.*;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -15,72 +17,78 @@

@Slf4j
@RestControllerAdvice
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthAdviceController {

/**
* 502 Bad Gateway
* 외부 API 연동 중 에러가 발생할 경우 발생하는 Exception
*/
@ExceptionHandler(BadGatewayException.class)
protected ResponseEntity<Object> handleBadGatewayException(final BadGatewayException exception) {
protected ResponseEntity<ErrorResponse> handleBadGatewayException(final BadGatewayException exception) {
log.warn("BadGatewayException: {}", exception.getMessage(), exception);
// add event publisher for let me know in slack or other application
return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body("bad gateway exception");

return ErrorResponse.toResponseEntity(HttpStatus.BAD_GATEWAY, "bad gateway exception");
}

/**
* 404 Not Found
* 회원가입이 안되어 있는 경우
*/
@ExceptionHandler(UserNotFoundException.class)
protected ResponseEntity<Object> handleUserNotFoundException(final UserNotFoundException exception) {
protected ResponseEntity<ErrorResponse> handleUserNotFoundException(final UserNotFoundException exception) {
log.info("UserNotFoundException: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.NOT_FOUND).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.NOT_FOUND, exception.getMessage());
}

/**
* 400 Bad Request
* OAuth 요청 정보가 적절하지 못한 경우
*/
@ExceptionHandler(InvalidParameterException.class)
protected ResponseEntity<String> handleParameterIsNotValidException(final InvalidParameterException exception) {
protected ResponseEntity<ErrorResponse> handleParameterIsNotValidException(final InvalidParameterException exception) {
log.info("InvalidParameterException: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.BAD_REQUEST, exception.getMessage());
}

/**
* 409 Conflict
* 이미 동일한 OAUTh로 등록한 회원이 존재하는 경우
*/
@ExceptionHandler(OAUthExistException.class)
protected ResponseEntity<String> handleOAuthUserExistException(final OAUthExistException exception) {
protected ResponseEntity<ErrorResponse> handleOAuthUserExistException(final OAUthExistException exception) {
log.info("OAUthExistException: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.CONFLICT).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.CONFLICT, exception.getMessage());
}

/**
* 401 Unauthorized
* token이 적절하지 않을 경우
*/
@ExceptionHandler({AuthHeaderOmittedException.class, TokenValidationException.class, TokenExpireExcetion.class, ExpiredJwtException.class})
protected ResponseEntity<String> handleUnAuthorizedException(final RuntimeException exception) {
@ExceptionHandler({
AuthHeaderOmittedException.class,
TokenValidationException.class,
TokenExpireExcetion.class,
ExpiredJwtException.class
})
protected ResponseEntity<ErrorResponse> handleUnAuthorizedException(final RuntimeException exception) {
log.info("UnAuthException: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.UNAUTHORIZED, exception.getMessage());
}

/**
* 403 Forbidden
* 접근 권한이 없을 경우
*/
@ExceptionHandler(ForbiddenException.class)
protected ResponseEntity<String> handleForbiddenException(final RuntimeException execException) {
protected ResponseEntity<ErrorResponse> handleForbiddenException(final RuntimeException execException) {
log.info("ForbiddenException: {}", execException.getMessage(), execException);

return ResponseEntity.status(HttpStatus.FORBIDDEN).body(execException.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.FORBIDDEN, execException.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import com.yapp.sharefood.user.domain.User;
import com.yapp.sharefood.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Optional;

@Service
Expand All @@ -24,6 +26,12 @@ public class AuthService {
private final UserRepository userRepository;
private final TokenProvider tokenProvider;

@Profile("local")
@PostConstruct
void setup() {
System.out.println(">>>> token: " + tokenProvider.createToken(User.builder().id(16L).build()));
}

public OAuthDto authenticate(AuthRequestDto authRequestDto) {
OAuthProfile profile = authenticationManager.requestOAuthUserInfo(authRequestDto.getOauthType(), authRequestDto.getAccessToken());
User existUser = userRepository.findByOAuthIdAndOAuthType(profile.getOauthId(), authRequestDto.getOauthType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,29 @@

import com.yapp.sharefood.bookmark.exception.BookmarkAlreadyExistException;
import com.yapp.sharefood.bookmark.exception.BookmarkNotFoundException;
import com.yapp.sharefood.common.error.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class BookmarkAdviceController {

@ExceptionHandler(BookmarkNotFoundException.class)
protected ResponseEntity<Object> handleBookmarkNotFoundException(final BookmarkNotFoundException exception) {
protected ResponseEntity<ErrorResponse> handleBookmarkNotFoundException(final BookmarkNotFoundException exception) {
log.info("BookmarkNotFoundException: {}", exception.getMessage(), exception);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.NOT_FOUND, exception.getMessage());
}

@ExceptionHandler(BookmarkAlreadyExistException.class)
protected ResponseEntity<Object> handleBookmarkAlreadyExistException(final BookmarkAlreadyExistException exception) {
protected ResponseEntity<ErrorResponse> handleBookmarkAlreadyExistException(final BookmarkAlreadyExistException exception) {
log.info("BookmarkAlreadyExistException: {}", exception.getMessage(), exception);
return ResponseEntity.status(HttpStatus.CONFLICT).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.CONFLICT, exception.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.yapp.sharefood.common.advice;

import com.yapp.sharefood.common.error.ErrorResponse;
import com.yapp.sharefood.common.exception.BadRequestException;
import com.yapp.sharefood.common.exception.InvalidOperationException;
import com.yapp.sharefood.common.exception.file.FileTypeValidationException;
import com.yapp.sharefood.common.exception.file.FileUploadException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
Expand All @@ -20,41 +22,57 @@ public class CommonAdviceController {
* file upload 실패
*/
@ExceptionHandler(FileUploadException.class)
protected ResponseEntity<Object> handleFileUploadException(final RuntimeException exception) {
protected ResponseEntity<ErrorResponse> handleFileUploadException(final RuntimeException exception) {
log.info("FileUploadException: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.BAD_GATEWAY, exception.getMessage());
}

/**
* 400 Bad Request
* file format 실패
*/
@ExceptionHandler({FileTypeValidationException.class, BadRequestException.class})
protected ResponseEntity<Object> handleBadRequestException(final RuntimeException exception) {
@ExceptionHandler({
FileTypeValidationException.class,
BadRequestException.class,
BindException.class
})
protected ResponseEntity<ErrorResponse> handleBadRequestException(final RuntimeException exception) {
log.info("File type or BadRequest: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.BAD_REQUEST, exception.getMessage());
}

/**
* 500 Interval Server Error
* 적절하지 못한 Exception 발생
*/
@ExceptionHandler({InvalidOperationException.class})
protected ResponseEntity<Object> handleInvalidOperationException(final RuntimeException exception) {
@ExceptionHandler(InvalidOperationException.class)
protected ResponseEntity<ErrorResponse> handleInvalidOperationException(final RuntimeException exception) {
log.info("InvalidOperationException: {}", exception.getMessage(), exception);

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage());
}

/**
* 400 Bad Request Error
* 적절하지 못한 Method Type
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> mappingException(MethodArgumentNotValidException e) {
log.error("MethodArgumentNotValidException: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
public ResponseEntity<ErrorResponse> mappingException(final MethodArgumentNotValidException exception) {
log.error("MethodArgumentNotValidException: {}", exception.getMessage(), exception);

return ErrorResponse.toResponseEntity(HttpStatus.BAD_REQUEST, exception.getMessage());
}

/**
* 500 Interval Server Error
* 예상하지 못한 에러
*/
@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handlerForBaseException(final Exception exception) {
log.error("Error: {}", exception.getMessage(), exception);

return ErrorResponse.toResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR, "Interval Server Error");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.yapp.sharefood.common.error;

import lombok.Getter;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

@Getter
public class ErrorResponse {
private final String message;

public ErrorResponse(String message) {
this.message = message;
}

public static ResponseEntity<ErrorResponse> toResponseEntity(HttpStatus httpStatus, String errorMessage) {
return ResponseEntity
.status(httpStatus)
.body(
new ErrorResponse(errorMessage)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
package com.yapp.sharefood.favorite.advice;

import com.yapp.sharefood.common.error.ErrorResponse;
import com.yapp.sharefood.favorite.exception.FavoriteNotFoundException;
import com.yapp.sharefood.favorite.exception.TooManyFavoriteException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class FavoriteAdviceController {
@ExceptionHandler(FavoriteNotFoundException.class)
protected ResponseEntity<Object> handleFavoriteNotFoundException(final FavoriteNotFoundException exception) {
protected ResponseEntity<ErrorResponse> handleFavoriteNotFoundException(final FavoriteNotFoundException exception) {
log.info("FavoriteNotFoundException: {}", exception.getMessage(), exception);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.NOT_FOUND, exception.getMessage());
}

@ExceptionHandler(TooManyFavoriteException.class)
protected ResponseEntity<Object> handleTooManyFavoriteException(final TooManyFavoriteException exception) {
protected ResponseEntity<ErrorResponse> handleTooManyFavoriteException(final TooManyFavoriteException exception) {
log.info("handleTooManyFavoriteException : {}", exception.getMessage(), exception);
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.TOO_MANY_REQUESTS, exception.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package com.yapp.sharefood.flavor.advice;

import com.yapp.sharefood.common.error.ErrorResponse;
import com.yapp.sharefood.flavor.exception.FlavorNotFoundException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
public class FlavorAdviceController {

@ExceptionHandler(FlavorNotFoundException.class)
protected ResponseEntity<Object> handleFlavorNotFoundException(final FlavorNotFoundException exception) {
protected ResponseEntity<ErrorResponse> handleFlavorNotFoundException(final FlavorNotFoundException exception) {
log.info("FlavorNotFoundException: {}", exception.getMessage(), exception);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(exception.getMessage());
return ErrorResponse.toResponseEntity(HttpStatus.NOT_FOUND, exception.getMessage());
}
}
Loading

0 comments on commit 9fe22fa

Please sign in to comment.