개발 환경
- 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": "/"
}
어디에서 기본 에러 응답 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) {
// ...
}
}
에러 응답하는 곳
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);
}
}
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;
}
}
Spring Boot DevTools의 영향
DevTools를 포함시키면 아래 설정들이 자동으로 들어가서 에러 응답이 화려해진다.사용자에게 노출하지 않고 싶은 필드도 자동으로 추가된다.
server.error.include-binding-errors=always
server.error.include-message=always
server.error.include-stacktrace=always
gradle에서 다음과 같이 추가되어 있다면, 로컬에서 gradle bootRun
으로 실행할 때에만 포함되고, jar 빌드할 때에는 포함되지 않는다.
즉, 별다른 설정을 하지 않아도 운영 환경에는 적용되지 않는다.
dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
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
방법 2
아래 설정을 application.properties에 포함시킨다.
- 장점: devtools로 인해 적용되는 properties를 한번에 끌 수 있다.
spring.devtools.add-properties=false
Top comments (0)