[스프링부트 blogV3] 3. java로 이해하는 springboot의 예외 처리 2

silver's avatar
Feb 03, 2025
[스프링부트 blogV3] 3.  java로 이해하는 springboot의 예외 처리 2

SpringBoot에서의 오류처리 흐름

notion image
try-catch -> 여기 코드에서 제어한다 throw를 날린다 -> 나를 호출하는 애한테 위임한다.

Repository

: 는 db와 연결하는 책임만 있기 때문에 repository에서 예외를 처리하지 않는다. → throw로 위임
import java.util.Arrays; import java.util.List; public class Repository { public List<Integer> findAll() {//throws InterruptedException { /* try { Thread.sleep(1000); // thread는 쉴틈없이 일함 } catch (InterruptedException e) { throw new RuntimeException(e); }*/ return Arrays.asList(1,2,3,4,5); } public int findByID() { /** * 조회하다가 오류 [1.숫자를 리턴 -1을 받으면 오류] -> 안됨 : type이 달라질 수 있다. * 오류가 난 곳에서 처리할 수 없다 : 책임이 분리되어 있다. (try-catch(:오류가 난 곳에서 바로 처리하겠다) 사용할 수 없다.) * -> 예외를 처리하는 걸 만든다. aop **/ /* 현재 안터지기 때문에 try-catch 로 안하고 throw로 그냥 터트린다. try { return 1; }catch (Exception e) { throw new RuntimeException("db에서 오류났어"); // 실행 중에 터지는 exception들의 최상위 부모 }*/ throw new RuntimeException("db에서 오류났어"); //-> service의 상세보기로 위임한다. } }

Service

: 에서 오류를 잡을 수 있지만 service 레이어의 책임이 아니므로 throw로 위임하거나 try-catch로 오류를 잡지 않고 controller로 자동위임시킨다.
import java.util.List; public class Service { private final Repository repo; public Service(Repository repo) { this.repo = repo; } public List<Integer> 목록보기() { return repo.findAll(); } public int 상세보기() { return repo.findByID(); } }

Controller

: 응답의 책임이 있으므로 오류를 try-catch로 controller에서 잡아도 되지만 오류를 자동위임시켜 DispatcherServlet으로 넘겨준다.
import java.util.List; public class Controller { private Service service; public Controller(Service service) { this.service = service; } public void list(){ List<Integer> models = service.목록보기(); for(Integer model : models){ System.out.println("rendering : "+model); } } public void detail(){ // try{ int model = service.상세보기(); System.out.println("rendering : "+model); // } catch (Exception e){ // System.out.println("error : "+e.getMessage()); // } } }

DispatcherServlet

: 위임받은 오류를 ControllerAdvice로 넘겨주기 위해 ControllerAdvice의 의존성을 주입한다.
// dispatcherServlet은 main으로 가니까 throw 날리면 걍 터져서 오류남 -> 여기서 오류처리해야한다. public class DispatcherServlet { private final Controller con; private final ControllerAdvice controllerAdvice; // 생성자 public DispatcherServlet(Controller con, ControllerAdvice controllerAdvice) { this.con = con; this.controllerAdvice = controllerAdvice; } 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){ // 0. 컴퍼넌스 스캔과 인보크는 java의 reflection으로 프로세스를 때릴 때 발생한다. // 1. 컴퍼넌트 스캔 @ControllerAdvice // 2. invoke(호출): 맞는 매개변수 타입을 찾아 때려준다. // -> 여기에서는 RuntimeException이므로 RuntimeException 매개변수를 가진 친구를 찾아서 때린다. controllerAdvice.process(e); } } }

ControllerAdvice

: 에러 처리
public class ControllerAdvice { public void process(RuntimeException e){ System.out.println("에러 공통 처리 : " + e.getMessage()); } }
 
Share article

silver