[에러처리101] 스프링에서 Exception 공통 처리하기

Waldo·2020년 11월 18일
4
post-thumbnail

Exception을 전역으로 처리하고 싶어요

@RestControllerAdvice
public class ErrorControllerAdvice {

  @ExceptionHandler(value = Exception.class)
  @ResponseStatus(value = HttpStatus.BAD_REQUEST)
  protected ResponseEntity<ErrorResponse> handleException(Exception e) {
    ErrorResponse response = ErrorResponse.of(ErrorCode.TEMPORARY_SERVER_ERROR);
    response.setDetail(e.getMessage());
    return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
  }
  
  @ExceptionHandler(value = NoSuchElementException.class)
  @ResponseStatus(value = HttpStatus.BAD_REQUEST)
  protected ResponseEntity<ErrorResponse> handleNoSuchElementException(Exception e) {
    ErrorResponse response = ErrorResponse.of(ErrorCode.RESOURCE_NOT_FOUND);
    response.setDetail(e.getMessage());
    return new ResponseEntity<>(response, HttpStatus.NO_CONTENT);
  }
  
  //요 밑으로 쭉쭉 추가적인 ExceptionHandler들을 추가해서 처리합니다
  
  /* Custom Error Handler */
  @ExceptionHandler(value = CustomException.class)
  @ResponseStatus(value = HttpStatus.BAD_REQUEST)
  protected ResponseEntity<ErrorResponse> handleCustomException(CustomException e) {
    ErrorResponse response = ErrorResponse.of(e.getErrorCode());
    response.setDetail(e.getMessage());
    return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
  }
}

RestControllerAdvice와 ExceptionHandler를 사용해 공통 처리

  • Exception이 나는 경우 간편하게 globally 처리가 가능합니당
    • 컴포넌트스캔을 통해서 컴포넌트로 생성되고 Controller로 선언된 모든 컴포넌트에서 일어나는 Exception을 공통 처리해버림
    • 로직 상 Error처리 하는 경우에는 CustomException을 생성해서 처리하도록 구현
    • Exception.class 자체를 잡아서 웬만한 에러들은 공통으로 처리하고, 세부 Exception들은 로직에 따라서 세부적으로 처리하도록 구현
    • @ResponseStatus로 Httpstatus를 지정해 줍니다

      TMI.
      저는 특별한 경우가 아니면
      BadRequest(400)으로 통일
      & Enum으로 선언된 에러코드를 사용
      & 공통된 클래스로 동일 json포맷으로 wrapping

      • 프론트엔드에서 메시지를 공통 처리하기 용이하도록 했습니당
      요러면 ErrorControllerAdvice 클래스 하나에 어노테이션 붙여서 생성하면 끄읕! 😎

예를 들면, 아래와 같이 작성한 Controller/Service에서 Exception을 던지는 경우에
알아서 ExceptionHandler가 동작하도록 연결되어 있는 상태인 거죵

  @ApiOperation(value = "그룹 조회")
  @GetMapping(value = "/{groupId}")
  @ResponseBody
  public GroupDto.Response getGroup(@PathVariable Long groupId) {
    Organization group = this.organizationJpaRepository
        .findByUseYnAndAndOrgIdAndType("Y", groupId, this.GROUP)
        .orElseThrow(NoSuchElementException::new);
    return this.customMapper.map(group, GroupDto.Response.class);
  }

다음 시리즈는 ErrorCode를 Enum처리 하고 공통 포맷으로 보내는 방법에 대해 이야기해보려고 합니다 (아래 요 코드처럼요)

    ErrorResponse response = ErrorResponse.of(ErrorCode.INVALID_TOKEN);

다음글

Enum으로 에러 코드 관리하기 😄

profile
늘어가는 연차, 애매해진 경력을 딛고 하고 싶은 거 다 하고 싶은 (아직은) 백엔드 개발자

0개의 댓글