Spring API 예외처리 / ResponseEntitiy
예외 처리를 따로 배우는 이유!
1. 웹 애플리케이션의 “예외”에 대하여 다시 한 번 인지할 필요가 있습니다.
2. 웹 애플리케이션에서의 에러를 Client와 Server 모두가 잘 알지 못하면, 서비스하는 환경에서 발생하는 에러에 대해서 제대로 대응 할 수가 없습니다.
3. AOP를 배웠던 만큼, 에러를 처리하는 것 역시 관심사를 분리해서 더 효율적으로 처리 할 수 있지 않을까 고민해보는 시간이 필요해서 입니다.

서버가 응답을 보낼 때 start-line에 있는 응답 코드를 보겠습니다. 응답 헤더에는 API 요청에 대한 상태코드를 함께 보냅니다.
Response 메시지 :
start-line (상태줄) : API 요청 결과 (상태 코드, 상태 텍스트) // HTTP/1.1 404 Not Found
(복습)
200 성공
300 redirection
400 클라이언트 에러 // e.g request api 가 다를 경우
500 서버 에서 에러.....
이런 에러를 잘 표현 하기 위해서 srpring 에서는
HttpStatus Emun 을 제공 해줍니다.
public enum HttpStatus {
// 1xx Informational
CONTINUE(100, Series.INFORMATIONAL, "Continue"),
// ...
// 2xx Success
OK(200, Series.SUCCESSFUL, "OK"),
CREATED(201, Series.SUCCESSFUL, "Created"),
// ...
// 3xx Redirection
MULTIPLE_CHOICES(300, Series.REDIRECTION, "Multiple Choices"),
MOVED_PERMANENTLY(301, Series.REDIRECTION, "Moved Permanently"),
FOUND(302, Series.REDIRECTION, "Found"),
// ...
// --- 4xx Client Error ---
BAD_REQUEST(400, Series.CLIENT_ERROR, "Bad Request"),
UNAUTHORIZED(401, Series.CLIENT_ERROR, "Unauthorized"),
PAYMENT_REQUIRED(402, Series.CLIENT_ERROR, "Payment Required"),
FORBIDDEN(403, Series.CLIENT_ERROR, "Forbidden"),
// ...
// --- 5xx Server Error ---
INTERNAL_SERVER_ERROR(500, Series.SERVER_ERROR, "Internal Server Error"),
NOT_IMPLEMENTED(501, Series.SERVER_ERROR, "Not Implemented"),
BAD_GATEWAY(502, Series.SERVER_ERROR, "Bad Gateway"),
// ...
주의 !
@Deplicated 가 있으면 더이상 허용 되지 않는 다는 뜻 입니다.
보통 버전이 업그레이드 되면서 필요 없어진 emun 들에 게 추가가 됩니다.
그래서 버젼 업 하면 사용하던게 안되는 상황이 발생합니다.
ResponseEntitiy
api 요청을 받을때 사용했습니다.
하지만 api 응답을 할때도 사용이 가능 합니다.
Spring에서 제공하는 ResponseEntity 클래스를 사용해보겠습니다.
//
우선 객체 RestApiException 을 만듭니다.
@Getter
@AllArgsConstructor
public class RestApiException {
private String errorMessage;
private int statusCode;
}
@PostMapping("/folders")
public ResponseEntity<RestApiException> addFolders(@RequestBody FolderRequestDto folderRequestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
try {
List<String> folderNames = folderRequestDto.getFolderNames();
folderService.addFolders(folderNames, userDetails.getUser());
return new ResponseEntity<>(HttpStatus.OK);
} catch(IllegalArgumentException ex) {
RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.BAD_REQUEST.value());
return new ResponseEntity<>(
// HTTP body
restApiException,
// HTTP status code
HttpStatus.BAD_REQUEST);
}
}
성공 했을때
return new ResponseEntity<>(HttpStatus.OK);
실패 했을때
RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.BAD_REQUEST.value());
return new ResponseEntity<>( restApiException, HttpStatus.BAD_REQUEST);
restApiException 는 HTTP body
HttpStatus.BAD_REQUEST 은 HTTP status code
이렇게 나뒤어서 응답을 내주는 것 을 볼 수 있습니다. 에러문구도 캐치하고,
그에 따라서 어느 부문에서 오류가 났는지 적어서 보내 줄 수 있습니다.
@ExceptionHandler 사용
@ExceptionHandler 는 Spring에서 예외처리를 위한 애너테이션
이 애너테이션은 특정 Controller에서 발생한 예외를 처리하기 위해 사용됩니다.
@ExceptionHandler 가 붙어있는 메서드는 Controller에서 예외가 발생했을 때 호출 되며, 해당 예외를 처리하는 로직을 담고 있습니다.
AOP를 이용한 예외처리 방식 ( try catch할 필요없음)
@ExceptionHandler({IllegalArgumentException.class})
public ResponseEntity<RestApiException> handleException(IllegalArgumentException ex) {
RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.BAD_REQUEST.value());
return new ResponseEntity<>(
restApiException, // HTTP body
HttpStatus.BAD_REQUEST // HTTP status code
);
}
p.s
에러가 있을때 클라 쪽에저

