Spring 예외 처리(1)

오성민·2022년 10월 30일
0

spring

목록 보기
3/17
post-thumbnail

혼자서 프로젝트를 진행하면서 한 가지 궁금증이 생겼다.
그것은 바로 적절한 예외 처리이다. 내가 생각했을 때 적절하게 예외를 처리하지 않는다면 개발자는 어떠한 예외가 발생한지 모르고 그렇다면 프로그램을 수정하기도 힘들고 이슈를 추적하기도 쉽지가 않습니다. 최악으로는 프로그램이 죽을 수도 있습니다.
이러한 문제를 방지하고 궁금증을 해결하기 위해서 글을 작성한다.

예외 처리 방법

예외 처리 회피

throws 문으로 선언해서 예외가 발생하면 알아서 해당 메소드를 호출한 쪽으로 던져지게 하거나 catch 문으로 일단 예외를 잡은 후에 로그를 남겨, 해당 이슈를 추적하고 다시 예외를 던지는 rethrow 할 수 있습니다.
하지만 이러한 방법을 남용하거나, 잘 이해하고 사용하지 않는다면 무책임한 회피가 될 수 있기 때문에 항상 경계를 하고 사용해야한다.

예외 전환

예외 회피와 비슷하게 예외를 복구해서 정상적인 상태를 만들 수 없기 때문에 예외를 메소드 밖으로 던지는 것이다.
하지만 예외 회피와는 달리, 적절한 예외로 전환해서 던집니다.

예외 전환의 목표

  1. 의미를 분명하게 해줄 예외로 바꾸는 것
  2. 예외를 처리하기 쉽고 단순하게 만들기 위해 포장wrap하는 것

어차피 복구하지 못할 예외라면 애플리케이션 코드에서는 런타임 예외로 포장해서 던져버리고,
아래의 모든 처리를 하는게 낫습니다.

✔️ 예외처리 서비스 등을 이용한 자세한 로그
✔️ 관리자에게 메일 등으로 통보
✔️ 사용자에게 안내 메시지를 보여주기

예외 복구

예를 들어 IOException이 발생했을 때,
사용자에게 상황을 알려주고 다른 파일을 이용하도록 안내해서 예외상황을 해결할 수 있습니다.
이처럼 다른 작업 흐름으로 자연스럽게 유도하여 처리하는 방법이 있습니다.

혹은 네트워크의 불안으로 발생한 SQLException 발생하는 경우에는 재시도를 해볼 수 있습니다.
일정 시간 대기했다가 다시 접속을 시도해보는 방법이 있습니다.

이렇게 사용자로 하여금 다시 예외가 발생하는 행동이 아닌 행동으로 유도하여 예외가 발생하지 않게 하는 것이다.

Spring의 예외 처리 방법

Spring은 기본적으로 예외가 발생하면 기본으로 탑재된 error controller가 호출되어 해당 error를 처리해준다.
기본으로 탑재된 error controller는 BasicErrorController 클래스에 정의된 메소드로 처리된다.
이 컨트롤러는

  • imestamp: 에러가 발생한 시간
  • status: 에러의 Http 상태
  • error: 에러 코드
  • path: 에러가 발생한 uri
  • exception: 최상위 예외 클래스의 이름(설정 필요)
  • message: 에러에 대한 내용(설정 필요)
  • errors: BindingExecption에 의해 생긴 에러 목록(설정 필요)
  • trace: 에러 스택 트레이스(설정 필요)

이러한 정보를 반환한다.
나는 이런 예외 처리를 나만의 방식으로 풀어내고 싶었지만 해당 클래스를 수정하기에는 너무 복잡하다고 생각이 들어서 다른 방식을 찾아보았다.

1. ResponseStatus

해당 방법은 @ResponseStatus라는 어노테이션을 메소드에 달아놓아서 호출되었을 때 무조건 내가 설정해놓은 StatusCode를 반환한다.
이러한 방식은 유연성이 너무 떨어진다. 나는 상황에 맞게 code와 message를 전달하고 싶었기 때문에 부적절하다고 생각하였다.

2. ExceptionHandler

해당 방법은 @ExceptionHandler라는 어노테이션을 메소드에 달아놓고 어노테이션에 매개변수로 내가 처리해주고 싶은 예외 클래스를 넣어주고, 메소드에 매개변수에 동일한 클래스의 변수를 넣어준다.
이러한 방식은 내가 생각했었던 것을 구현하기에 적절했다. 매우 유연하게 처리할 수 있다고 생각하여서 현재 이 방법을 사용하고 있다.
나는 현재 HumanError가 발생하였을 때 처리를 해줘야할 때 사용을 하고 있다.
try/catch, throws, ExceptionHandler를 적절하게 섞어서 사용하는 방법은 좀 더 많이 고민을 해봐야할 것 같다.

이 글에서는 나머지 2가지 방식인 ResponseStatusException과 ControllerAdvice, RestControllerAdvice 는 다루지 않았다.
아직 내가 사용해보지 않았기 때문에 정확히 이해를 하지 못했다.
다음에는 이 3가지를 사용해보고 이해한 후에 Spring 예외 처리 흐름을 정확하게 이해한 후에 같이 포스팅을 해야겠다.

profile
풀스택을 지향하는 개발자

0개의 댓글