Spring Boot Exception Handling

2024. 12. 17. 23:55Spring Boot

기본적으로 Spring Boot에서 Exception이 발생하면 Basic Error Controller를 호출해서 해당 페이지가 나온다

 

이 페이지는 기본적으로 Execption이 발생하면 출력되도록 설정되어 있어서 기본적은 오류 내용을 표기해준다

 

다만 문제가 있는데

무조건 Status Code가 500으로 나오고

불필요한 내용이 많이 담기고

내용도 명확하지 않고

작동 방식이 컨트롤러를 한 번 더 호출하는 방식이라 필터나 인터셉터 관련 처리도 필요하다

 

 

package com.example.mvc.exception;

import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/error")
public class BasicErrorController extends AbstractErrorController {
    public BasicErrorController(ErrorAttributes errorAttributes, List<ErrorViewResolver> errorViewResolvers) {
        super(errorAttributes, errorViewResolvers);
    }

    @RequestMapping
    public ResponseEntity<String> basic_error() {
        return ResponseEntity.status(500).body("this is basic");
    }
}

 

 

 

물론 커스텀을 한 Basic Error Controller를 등록 시킬 수 있긴 한데

주로 다른 방법을 통해 Exception을 처리한다.

 

 

 

이제 진짜로 자주 쓰이는 Exception을 다룰 때 사용하는 Exception Handler를 알아보겠다.

 

우선 한 Controller에서 Exception을 다룰 때는 Controller 내부에 Exception Handler를 만들어 사용하고

전역으로 다룰 때는 ControllerAdvice를 정의하고 그 안에 Exception Handler를 만들어 사용한다.

 

작동 방식은 등록된 Exception이 발생 시 해당 Handler를 불러서 처리하는 방식이다.

이때 부모 Exception을 등록하면 자식 Exception의 Handler가 없을 때 부모 Exception의 Handler를 부른다.

 

만약 Handler를 정의하지 않으면 아까 말했던 BasicErrorController을 부른다.

 

https://data-flair.training/

 

 

 

Exception Handler)

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ResponseStatusException;


@Slf4j
@Controller
@RequestMapping("/test/exception")
public class exception_controller {
    @GetMapping("/runtime/default")
    public String runtime_default() {
        throw new RuntimeException("runtime error test");
    }

    @GetMapping("/runtime/status")
    public String runtime_status() {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "bad request");
    }

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> runtime_exception(RuntimeException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage() + "  from controller exception handler");
    }

 

 

 

RestControllerAdvice)

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class global_exception_handler {
    @ExceptionHandler(RuntimeException.class)
    private ResponseEntity<String> runtimeExceptionHandler(RuntimeException e) {
        return ResponseEntity.status(401).body(e + " from rest controller advice");
    }
}

 

 

기본적으로 해당 컨트롤러에 Exception Handler가 정의 되어 있으면 그 쪽을 우선시 하고 없으면 ControllerAdvice를 찾는다.

즉 우선 순위는

컨트롤러의 Exception Handler > ControllerAdvice의 Handler > BasicErrorController이다.

 

'Spring Boot' 카테고리의 다른 글

JPA란?  (0) 2024.12.01
Spring Data DTO  (0) 2024.12.01
JPA Paging  (0) 2024.11.28
JPQL  (0) 2024.11.28
Spring Cloud Eureka  (0) 2024.10.29