DEV Community

김민중
김민중

Posted on

Spring Boot : Default Exception Handling : 기본 에러 응답

개발 환경

  • Java 21
  • Spring Boot 3.2.4

기본 에러 응답

Spring Boot에서 아무 설정도 하지 않고 RestController 구성하여 예외 발생시키면 다음과 같은 형태의 response body를 응답한다.

{
    "timestamp": "2024-04-05T13:37:51.440+00:00",
    "status": 405,
    "error": "Method Not Allowed",
    "path": "/"
}
Enter fullscreen mode Exit fullscreen mode

어디에서 기본 에러 응답 body를 만드나?

어디에서 어떤 과정을 거쳐 이런 형태의 에러 응답을 하는지 궁금하여 간략하게 정리해보았다.
아래에 그 과정에서 알게된 몇 가지 설정도 적어두었다.

아래에서 1차 처리

package org.springframework.web.servlet.mvc.support;

public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {

    @Override
    @Nullable
    protected ModelAndView doResolveException(
            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
        // ...
    }
}
Enter fullscreen mode Exit fullscreen mode

에러 응답하는 곳

package org.springframework.boot.autoconfigure.web.servlet.error;

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {

    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        HttpStatus status = getStatus(request);
        if (status == HttpStatus.NO_CONTENT) {
            return new ResponseEntity<>(status);
        }
        Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        return new ResponseEntity<>(body, status);
    }
}
Enter fullscreen mode Exit fullscreen mode

response body 만드는 곳

package org.springframework.boot.autoconfigure.web.servlet.error;

@Order(Integer.MIN_VALUE)
public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {

    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = this.getErrorAttributes(webRequest, options.isIncluded(Include.STACK_TRACE));
        if (!options.isIncluded(Include.EXCEPTION)) {
            errorAttributes.remove("exception");
        }

        if (!options.isIncluded(Include.STACK_TRACE)) {
            errorAttributes.remove("trace");
        }

        if (!options.isIncluded(Include.MESSAGE) && errorAttributes.get("message") != null) {
            errorAttributes.remove("message");
        }

        if (!options.isIncluded(Include.BINDING_ERRORS)) {
            errorAttributes.remove("errors");
        }

        return errorAttributes;
    }
}
Enter fullscreen mode Exit fullscreen mode

Spring Boot DevTools의 영향

DevTools를 포함시키면 아래 설정들이 자동으로 들어가서 에러 응답이 화려해진다.사용자에게 노출하지 않고 싶은 필드도 자동으로 추가된다.

server.error.include-binding-errors=always
server.error.include-message=always
server.error.include-stacktrace=always
Enter fullscreen mode Exit fullscreen mode

gradle에서 다음과 같이 추가되어 있다면, 로컬에서 gradle bootRun으로 실행할 때에만 포함되고, jar 빌드할 때에는 포함되지 않는다.
즉, 별다른 설정을 하지 않아도 운영 환경에는 적용되지 않는다.

dependencies {
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
Enter fullscreen mode Exit fullscreen mode

maven에서도 spring-boot-maven-plugin이 똑같은 역할을 해준다.

만약 개발 환경에서 운영 환경의 에러 응답을 확인하고 싶다면 다음 두 가지 방법 중 하나를 적용하면 된다.

방법 1

아래 설정을 application.properties에 포함시킨다.
DevTools가 없을 때의 기본 값이다.

  • 장점: 에러 응답에 관한 것만 적용할 수 있다.
server.error.include-binding-errors=never
server.error.include-message=never
server.error.include-stacktrace=never
Enter fullscreen mode Exit fullscreen mode

방법 2

아래 설정을 application.properties에 포함시킨다.

  • 장점: devtools로 인해 적용되는 properties를 한번에 끌 수 있다.
spring.devtools.add-properties=false
Enter fullscreen mode Exit fullscreen mode

Top comments (0)