본문 바로가기

카테고리 없음

[spring boot] 에러처리기

스프링부트: BasicErrorController

스프링부트에는 기본 에러를 처리해주는 컨트롤러가 있다.

이름은 BasicErrorController

아래와 같은 계층 구조이다.

레퍼런스 29.1.11 Error Handling에서 자세한 내용을 볼 수 있다.

 

잘못된 URL에 요청을 보내면 아래와 같은 형식으로 출력을 한다.

{ 
   "timestamp":"2019-10-14T07:06:11.132+0000",
   "status":404,
   "error":"Not Found",
   "message":"No message available",
   "path":"/membership/"
}

이 에러 형식은 스프링 부트의 DefaultErrorAttributes가 수행한다.

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

@Order(Ordered.HIGHEST_PRECEDENCE)
public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {
	// ..
	@Override
	public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
		Map<String, Object> errorAttributes = new LinkedHashMap<>();
		errorAttributes.put("timestamp", new Date());
		addStatus(errorAttributes, webRequest);
		addErrorDetails(errorAttributes, webRequest, includeStackTrace);
		addPath(errorAttributes, webRequest);
		return errorAttributes;
	}
    // ..

재미있는 것은 status 코드가 null 일 경우 999라는 값으로 넣는 fallback이 있다.

private void addStatus(Map<String, Object> errorAttributes, RequestAttributes requestAttributes) {
	Integer status = getAttribute(requestAttributes, "javax.servlet.error.status_code");
	if (status == null) {
		errorAttributes.put("status", 999);
		errorAttributes.put("error", "None");
		return;
	}
	errorAttributes.put("status", status);
	try {
		errorAttributes.put("error", HttpStatus.valueOf(status).getReasonPhrase());
	}
	catch (Exception ex) {
		// Unable to obtain a reason
		errorAttributes.put("error", "Http Status " + status);
	}
}

스프링: DefaultHandlerExceptionResolver

스프링에서는 예외 처리를 위한 처리기로 DefaultHandlerExceptionResolver가 있다.

 

서드 파티

기본 에러 응답이 맘에 들지 않는다면 서드 파티 에러 처리 스타터를 스프링 부트에 붙일 수도 있다.

Errors Spring Boot Starter (GitHub)

DZone: REST API Error Handling With Spring Boot 

 

이 라이브러리는 DefaultHttpErrorAttributesAdapter에서 에러 형식을 정의하고 있다.

ErrorsAutoConfiguration 에서 HttpErrorAttributesAdapter 형식의 빈이 없을 경우 DefaultHttpErrorAttributesAdapter 구현체로 빈을 만들도록 되어 있다.

package me.alidg.errors.conf;

@ConditionalOnWebApplication
@EnableConfigurationProperties(ErrorsProperties.class)
public class ErrorsAutoConfiguration {
    // ..
    @Bean
    @ConditionalOnBean(WebErrorHandlers.class)
    @ConditionalOnMissingBean(HttpErrorAttributesAdapter.class)
    public HttpErrorAttributesAdapter httpErrorAttributesAdapter(ErrorsProperties errorsProperties) {
        return new DefaultHttpErrorAttributesAdapter(errorsProperties);
    }