문제
지금 식별한 부분중 처리되지 않는 에러
MethodArgumentNotValidException 400
MissingServletRequestParameterException 400
HandlerMethodValidationException 400
NoHandlerFoundException 404
HttpRequestMethodNotSupportedException 405
이들은 공통응답처리가 되지 않았다
valid, validate, 없는 url과 없는 method로 호출할때가 공통응답 처리가 되지 않았다.
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler
이유는 ResponseEntityExceptionHanlder를 상속 받았기 때문 여기서 handler로 지정해주지 않은 에러들은 다 처리했기 때문
// 모든 예외를 처리하는 핸들러
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleAllExceptions(Exception e) {
log.error("Exception: {}", e.getMessage(), e);
return ExceptionHandlerUtil.handleExceptionInternal(CommonExceptionCode.INTERNAL_SERVER_ERROR);
}
이 부분에서 모든 예외를 잘처리해주는 줄 알았지만 그것도 아니였다.
해결 방법 (valid, validate 등)
1. Override
ResponseEntityExceptionHandler 안에 있는 에러응답 메서드들을 override를 통해서 응답 처리를 전부다 바꾸는 것
- 장점 : 응답 처리를 하지 않은 것도 spring의 기본 예외 처리를 적용해서 알려주게됨
- 단점 : 공통응 답처리가 되지 않은 예외가 front로 전달될 위험이 있음
2. 확장을 받지 않고 ExceptionHandler 사용
extends로 확장을 받지 않고 필요한 예외들을 ExceptionHandler로 처리해 주는 것
- 장점 : 응답 처리를 같은 형식으로 처리할수 있어서 유지 보수성이 높아진다는 것 (불필요한 override를 하지 않아서)
- 단점 : 예외처리 하지 않은 예외들은 모두 INTERNAL_SERVER_ERROR 처리가 된다는 것
우리팀은 이 방식을 선택하기로 했다. 이후 예외처리하지 않은 예외들이 식별될 경우 프론트에 어떻게 알려줄지 토론하고 결정하는 방식으로 하려한다.
해결 방법 (url, method 없음)
이들은 ControllerAdvice에서 잡지 못하기 때문에 따로 처리를 해줘야한다.
1. ErrorAttributes
- 장점 : 모든 에러를 처리하게 된다.
- 단점 : 에러 코드를 식별해서 구분할수 없으며 단일 처리를 하게 된다.
2. ErrorController
- 장점 : 에러 코드 식별 가능
- 단점 : 지정해준 에러만 처리 가능
나는 에러 코드마다 식별할수 있는 방식인 ErrorController를 상속 받는 방식을 택했다.
//handler로 잡지 못하는 에러들을 처리하는 컨트롤러
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public ResponseEntity<Object> handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
//NoHandlerFoundException 예외처리
if (status.equals(404)) {
return ExceptionHandlerUtil.handleExceptionInternal(CommonExceptionCode.NOT_FOUND);
}
//HttpRequestMethodNotSupportedException 예외처리
else if (status.equals(405)) {
return ExceptionHandlerUtil.handleExceptionInternal(CommonExceptionCode.METHOD_NOT_ALLOWED);
}
//404, 405에도 안잡히면 예상치 못한 예외처리
return ExceptionHandlerUtil.handleExceptionInternal(CommonExceptionCode.INTERNAL_SERVER_ERROR);
}
}
이를 통해서 page에러로 출력하던걸 공통응답 처리를 통해서 json형식으로 넘겨줄수 있게 됐다.
예외처리 우선 순위
1. Exception Handler
@Controller
public class MyController {
@ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handleMyCustomException(MyCustomException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("");
}
}
특정 컨트롤러나 전역 처리에서
2. ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGlobalException(Exception ex) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
}
}
전역 예외 처리
3. ErrorAttributes
@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
errorAttributes.put("message", "");
return errorAttributes;
}
}
에러에 대한 속성을 정의하는 곳
4. ErrorController
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public ResponseEntity<String> handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null && status.equals(404)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("");
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
}
}
에러가 처리되지 않았을 때 최종적으로 작동하는 곳
5. 기본 오류 페이지
모든 예외처리가 실패할시 기본 제공하는 오류 페이지를 표시함
참고
'Spring > Spring 기초' 카테고리의 다른 글
[Spring/기초] api 공통 응답 포맷 + 예외 처리 합치기 (2) (0) | 2024.07.15 |
---|---|
[Spring/기초] 전역 예외 처리 + Test Code (1) (0) | 2024.07.14 |
[Spring/기초] RestController 완벽 정리 (return type, 파라미터, 추가 개념 및 기능) (0) | 2024.06.23 |
[Spring/기초] 환경 변수 파일 사용하기 (env.properties) (0) | 2024.05.28 |
[Spring/기초] Service (0) | 2024.02.07 |
Coding, Software, Computer Science 내가 공부한 것들 잘 이해했는지, 설명할 수 있는지 적는 공간