예외 - 스프링 부트

바그다드·2023년 5월 23일
0

예외

목록 보기
3/9

지난 포스팅에서 서블릿을 활용한 예외 처리 방법에 대해서 알아보았다.
그런데 WebServerCustomizer를 생성하거나, 에러 페이지를 추가하고, 컨트롤러를 생성하는 등의 복잡한 과정이 필요했다. 이번에는 스프링부트를 활용하여 이 과정이 어떻게 생략되는지 확인해보자.

스프링부트 기본 제공 기능

  1. ErrorPage를 자동으로 등록한다.
    상태코드나 예외를 설정하지 않으면 new ErrorPage("/error")가 기본 에러 페이지로 등록된다.
    서블릿 밖으로 예외가 전달되거나, response.sendError()가 호출되면 모든 에러는 /error를 호출하게 된다.
  2. BasicErrorController라는 컨트롤러를 자동으로 빈으로 등록한다.
    1번에서 등록한 /error를 매핑해서 처리해준다.
  • 참고로 ErrorPage를 등록해주는 역할을 ErrorMvcAutoConfiguration이 한다.
  • 스프링 부트가 기본으로 제공하는 에러 메커니즘도 다른 기능과 마찬가지로 WebServerCustomizer처럼 사용자가 정의한 빈이 있다면 적용되지 않으므로 기존에 생성했던 WebServerCustomizer는 빈 등록을 하지 않도록 하자.
    그럼 코드로 구현하고 결과를 확인해보자

컨트롤러 등록

  • 예외를 발생시키기 위한 컨트롤러부터 생성해보자.
@Slf4j
@Controller
public class ServletExceptionController {

    @GetMapping("/error-ex")
    public void errorEx() {
        throw new RuntimeException("예외 발생!");
    }

    @GetMapping("/error-404")
    public void error404(HttpServletResponse response) throws IOException {
        response.sendError(404, "404오류!");
    }

    @GetMapping("/error-400")
    public void error400(HttpServletResponse response) throws IOException {
        response.sendError(400, "400오류!");
    }

    @GetMapping("/error-500")
    public void error500(HttpServletResponse response) throws IOException {
        response.sendError(500, "500오류!");
    }

뷰 생성

  • 이제 각 에러를 확인하기 위한 뷰를 생성하자.
  • 생성 후에 각 에러를 발생시키면

    따로 예외에 따라서 ErrorPage를 등록하지 않았는데도 각 예외에 매핑되는 뷰를 자동으로 찾아주는 것을 확인할 수 있다.
    이것 또한 마찬가지로 뷰를 선택하는 우선순위에 대한 규칙이 있다.

뷰 선택 우선순위

  1. 뷰 템플릿
    타임리프나 jsp같은 동적인 페이지가 높은 우선순위를 갖는다
    현재의 경우 resources/templates/error/500.html

  2. 정적 리소스(static, public)
    단순한 정적인 페이지일 경우
    resources/static/error/500.html

  3. 적용대상이 없을 때
    resources/templates/error.html

  • 또한 같은 패키지 안에서도 뷰의 이름이 얼마나 구체적이냐에 따라 우선순위가 정해지는데 예를 들어,
    resources/templates/error/500.html
    resources/templates/error/5xx.html
    이 두개의 뷰가 있을 경우 500.html이 높은 우선순위를 갖게 된다.
  • 만약 400에러가 발생했는데, 우리처럼 400.html이 존재하지 않는다면 4xx.html이 대신 매핑된다.
  • 예외의 경우도 결국 서버의 문제이므로 500에러와 같이 처리된다.

에러 정보 표시하기

  • BasicErrorController는 에러 정보를 model에 담아 뷰로 전송하는데, 이를 이용해 에러 정보를 확인할 수 있다.

    그런데 막상 해당 페이지로 접근해보면 에러 정보가 담겨있지 않은 것을 확인할 수 있는데, appllication.properties에 설정을 추가해주자.
server.error.include-exception=true
server.error.include-message=always
server.error.include-stacktrace=always
server.error.include-binding-errors=always
  • 여기서 각 키의 value에는
    never : 사용하지 않음
    always : 항상 사용

    on_param : 파라미터가 있을 때 사용
    등의 값이 들어갈 수 있다.
  • 하지만 이런 정보는 사용자에게도 불편함을 끼치고, 보안상 문제가 생길 수 있으므로 개발 서버에서만 사용하고 운영서버에서는 사용하지 않도록 하자.

그 외 스프링 부트 에러 관련 옵션

  • server.error.whitelabel.enabled=true : 에러 화면을 찾지 못했을 때, 스프링의 whitelabel 에러 페이지를 띄운다.
  • server.error.path=/error : 에러 페이지 경로로서, 스프링이 자동으로 등록하는 글로벌 에러 페이지 경로와 BasicErrorController의 경로에 함께 사용된다.
    근데 별로 쓸일이 없다고 한다.
  • 에러 공통 처리 컨트롤러를 수정하고 싶다면, ErrorController나 BasicErrorController를 상속받아서 사용하자.

출처 : 김영한 스프링MVC2편

profile
꾸준히 하자!

0개의 댓글