예외 처리 (기본 원리)

화낼거양's avatar
Nov 21, 2024
예외 처리 (기본 원리)
 
 
💡
해당 게시글은 Spring 예외 처리 과정을 배우기 전, 간단하게 원리를 알아가는 내용입니다.
 
 

먼저 Repository 클래스에서 조회를 하다가 오류가 발생했다고 가정

 
public class Repository { public List<Integer> findAll() { return Arrays.asList(1, 2, 3, 4, 5); } public int findById() { // 예제는 무조건 런타임예외를 발생시키도록 작성하였다. throw new RuntimeException("DB에서 오류 발생"); } }
 

throw new RuntimeException 과 같이 예외를 throw 하는 이유 :

 
숫자를 리턴(-1) X: 타입이 달라질 수 있기 때문에 권장하지 않습니다.
  • 설명: 메서드가 정상적으로 값을 반환해야 하는 경우와 오류가 발생했을 때의 반환 값을 구분하기 위해 숫자를 사용하면, 반환 타입이 달라질 수 있습니다. 예를 들어, 메서드가 일반적으로 양수 값을 반환해야 하는데, 오류 시 -1을 반환한다면, 호출자는 -1이 의미하는 바를 정확히 이해하고 처리해야 합니다. 이는 코드의 가독성을 떨어뜨리고 오류 처리의 일관성을 해칠 수 있습니다.
오류가 난 곳에서 처리 X: 책임이 분리되어 있기 때문에 권장하지 않습니다.
  • 설명: 오류가 발생한 곳에서 모든 오류 처리를 수행하면, 코드의 책임이 모호해지고 중복된 오류 처리 코드가 많이 생길 수 있습니다. 책임 분리를 통해 오류를 발생시키는 부분과 이를 처리하는 부분을 명확히 구분하면, 코드의 유지보수성과 가독성이 향상됩니다.
 
 

예외를 던지고, 적절한 곳에서 처리

 
따라서 1번과 2번의 이유 때문에 예외가 발생했을 때 exception을 throw 하고, 해당 예외의 책임이 있는 객체가 받아서 처리합니다.
  • 설명: 메서드가 예외 상황에 처했을 때, 적절한 예외를 던짐으로써 호출자가 이를 처리하도록 합니다. 이는 호출자가 해당 예외를 적절히 처리하거나 로그를 남길 수 있는 기회를 제공합니다. 또한, 예외를 던짐으로써 오류 처리 로직을 분리하여 코드의 책임을 명확히 합니다.
 
 
 
 
 
 
 

예외 처리하기

 
 
Spring에서는 @ControllerAdvice가 정의되어 있다면, DispatcherServlet은 발생한 예외를 해당 @ControllerAdvice로 전달합니다. 이를 통해 전역 예외 처리기를 사용하여 예외를 일괄적으로 처리할 수 있습니다.
💡

예외 처리 흐름 요약:

  • Repository -> Service -> Controller -> DispatcherServlet -> Filter -> Tomcat 순으로 예외가 전파될 수 있습니다.
 
아래의 예제에서는 ControllerAdvice 가 @ControllerAdvice 어노테이션을 가지고 있다는 가정하에 작성하였습니다.
 

DispatcherServlet

public class DispatcherServlet { private final Controller con; private final ControllerAdvice advice; public DispatcherServlet(Controller con, ControllerAdvice advice) { this.con = con; this.advice = advice; } public void route(String path) { try { if (path.equals("/")) { con.list(); } else if (path.equals("/board")) { con.detail(); } else { System.out.println("404 not found"); } } catch (RuntimeException e) { // 1. 컴포넌트 스캔 @ControllerAdvice // 2. invoke(호출) RuntimeException 매개변수를 가진 친구를 찾는다. advice.process(e); } } }
 
예외를 DispatcherServlet이 ControllerAdvice에게 위임하도록 작성하였습니다.
  • 생성자로 Controller와 ControllerAdvice를 매개 변수로 전달받고 초기화.
  • try 내용을 실행하다 예외를 전달 받으면 catch 의 advice.process(e); 메서드 호출
 

ControllerAdvice

public class ControllerAdvice { public void process(RuntimeException e) { System.out.println("에러 공통 처리 : " + e.getMessage()); } }
 
  • process 메서드에 런타임 에러를 전달 받으면 단순 콘솔 출력을 할 수 있도록 구현
(e.getMessage() : “DB에서 오류 발생” )

에러 발생시 출력되는 문구 :

 
notion image
 
 
Share article

moohyun