스프링 #9 예외 처리 1 - 오류 페이지 등록

함형주·2022년 10월 19일
0

spring

목록 보기
9/12

질문, 피드백 등 모든 댓글 환영합니다.

스프링에서 예외가 발생하면 이를 어떻게 처리하는 지 알아보겠습니다.

예외를 try-catch 문으로 잡으면 문제가 발생하지 않지만 만약 WAS(Web Application Server, 스프링 부트 사용시 TOMCAT)까지 예외가 전달될 시 적절한 오류 페이지를 클라이언트에게 제공해야합니다.

이번 블로그에선 스프링에서 예외가 WAS까지 어떻게 전달되고 오류 페이지를 보여주는지 정리하겠습니다.

서블릿 컨테이너에서 예외 처리

스프링은 서블릿 컨테이너를 포함하고 있고 예외 발생 시 서블릿 컨테이너를 통해 예외가 전달되기에 순수 서블릿에서 예외를 처리하는 방법을 알아보겠습니다.

서블릿은 두 가지 방식으로 예외를 전달합니다.

  1. Exception
  2. HttpServletResponse.sendError()

Exception

만약 애플리케이션 레벨에서 예외를 처리하지 못한다면 아래의 경로로 WAS 까지 예외가 전달됩니다. (필터와 인터셉터에 관한 내용은 이후 블로그에서 다룹니다.)

컨트롤러 -> 인터셉터 -> 서블릿 -> 필터 -> WAS

WAS까지 예외가 전달된다면 HTTP 상태코드 500을 반환합니다. (잘못된 경로로 요청시 404)

스프링에서 예외를 발생시키면 (RuntimeException 등) 인터넷 브라우저에서 스프링이 제공하는 오류 페이지를 확인할 수 있습니다.

톰캣이 제공하는 오류 페이지를 확인하려면 application.properties에서 설정이 필요합니다.
server.error.whitelabel.enabled=false

sendError()

단순히 Exception을 전달하는 것이 아니라 HttpServletResponse.sendError()를 사용하면 HTTP 상태 코드와 오류 메시지도 추가할 수 있습니다.

sendError(int sc) // HTTP 상태 코드
sendError(int sc, String msg)

사용하는 시점에 바로 예외가 발생하는 것이 아니라 서블릿에서 sendError()를 확인하고 이를 기반으로 오류 페이지를 제공할 수 있습니다.

WebServerFactoryCustomizer<ConfigurableWebServerFactory>를 상속받아 스프링 빈으로 등록하면 new ErrorPage()로 상태 코드에 따른 오류 페이지를 등록할 수 있습니다.

new ErrorPage(String path)
new ErrorPage(HttpStatus status, String path)
new ErrorPage(Class<? extends Throwable> exception, String path)

ex) ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404") or
ErrorPage(RuntimeException.class, "/error-page/500") // RuntimeException과 하위 타입

예외가 발생했을 때 해당 오류 페이지를 출력할 컨트롤러도 생성해야 합니다.

만약 WAS까지 예외(RuntimeException)가 전달되었다면 아래의 경로로 오류 페이지가 출력됩니다.
WAS에서 ErrorPage()확인 -> WAS가 "/error-page/500" 경로로 새로운 요청
-> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러("/error-page/500") -> View

스프링 부트에서 예외 처리

이 전까진 오류 페이지를 등록하여 출력하기 위해선 WebServerCustomizer를 생성하고 ErrorPage 추가, 예외 처리용 컨트롤러를 모두 직접 등록해서 사용해야 했지만 스프링 부트는 이 부분을 자동으로 설정해줍니다.

  1. ErrorPage 등록, 기본 경로는 "/error"
  2. BasicErrorController 등록

때문에 개발자는 별도의 설정 없이 오류 페이지만 등록하여 사용하면 됩니다. 정적 리소스나 뷰 템플릿에 오류 페이지를 만들어 사용할 수 있습니다.

스프링이 오류 페이지를 선택하는 규칙은 아래와 같습니다.

  1. 뷰 템플릿, 정적 리소스, 스프링 기본 페이지 순으로 매핑
  2. error/404.html, error/400.html, error/4xx.html, 을 등록했다면 자세한 것 부터 매핑(404 -> 400 -> 4xx) 4xx은 400번대 상태 코드 전체를 지칭함

에러 페이지 경로는 application.properties 에서 설정 가능합니다.
server.error.path=/error

BasicErrorController의 기능을 확장하고 싶다면 ErrorController(인터페이스)나 BasicErrorController를 상속 받아 기능을 추가할 수 있습니다.

profile
평범한 대학생의 공부 일기?

0개의 댓글