https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Exception.html
Exception (Java SE 17 & JDK 17)
All Implemented Interfaces: Serializable Direct Known Subclasses: AbsentInformationException, AgentInitializationException, AgentLoadException, AlreadyBoundException, AttachNotSupportedException, AWTException, BackingStoreException, BadAttributeValueExpExc
docs.oracle.com

- 모든 예외 클래스는 Throwable 클래스를 상속받고 있다.
- Throwable을 상속받는 클래스는 Error와 Exception이 있습니다.
- Error = 응용 프로그램이 포착하려고 해서는 안 되는 심각한 문제를 나타내는 하위 클래스입니다
- 해당 에러는 try-catch, throws Exception을 하여도 해결되지 않기에 해당 문법을 사용하지 않는다.
- Exception = 클래스 Exception 및 해당 하위 클래스는 Throwable합리적인 응용 프로그램에서 포착할 수 있는 조건을 나타내는 형식입니다
- Exception 같은 경우 수많은 하위 클래스가 존재하지만 이 중, RuntimeException과 그 외 예외로 나뉜다.
- Error = 응용 프로그램이 포착하려고 해서는 안 되는 심각한 문제를 나타내는 하위 클래스입니다
CheckedException VS UnCheckedException
- RuntimeException의 UnCheckedException, 그 외 Exception을 CheckedException이라고 한다.
- CheckedException 같은 경우 컴파일 단계에서 반드시 예외를 처리하여야 한다.
- throws Exception과 try-catch를 해주어야지만 컴파일 오류를 해결할 수 있다.
- UnCheckedException 같은 경우 실행단계에서 명시적 처리를 강제하지 않는다.
- NullPointException, IllegalArgmentException 같은 경우 충분히 피해갈 수 있지만 개발자의 부주의에 의해서 발생한 것이므로, 런타임 예외이다.
- 트랜잭션 같은 경우 checkedException 같은 경우 rollback을 하지 않지만, uncheckedException 같은 경우 rollback을 진행해준다.
Spring에서의 Exception 처리과정

- 그렇다면 Spring에서는 예외가 어떻게 발생되고 어떻게 처리를 해주어야 할까?
- Spring에서의 예외가 발생하는 부분은 크게 두 가지로 나눌 수 있다
- Dispatcher Servlet내에서 발생하는 예외 (Controller, Service, Repository 등등)
- Dispatcher Servlet전의 서블릿 (Filter)에서 발생하는 예외
- 스프링 MVC 에러 중 99프로는 DispatcherServlet에서 발생하기 때문에 DispatcherServlet내에서 발생하는 예외를 내부에서 자체적으로 해결할 수 있다
DispatcherServlet에서 발생한 예외 처리
- DispatcherServlet 내에서의 에러를 처리하는 방식에는 크게 3가지가 존재한다.
- Controller 레벨에서 처리
- Global 레벨에서 처리
- HandlerExceptionResolver를 이용한 처리
- Controller 레벨에서의 처리
- Controller에서 발생한 예외에 대해 Common 하게 처리할 수 있는 기능을 제공
- @ExceptionHandler 어노테이션을 통해 Controller의 메서드에서 throw된 Exception에 대한 공통적인 처리를 할 수 있도록 지원

예시 - DemoController내에서 발생한 DemoException에 대해서는 handleDemoException 메소드에서 모두 처리를 해준다
- Controller 메소드 내의 하위 서비스에서 Checked Exception이 발생하더라도, Controller 메소드 상위까지 예외를 throw 시키면@ExceptionHandler 어노테이션을 사용하여 Controller 전역적으로 예외처리가 가능하다
- Controller 메소드 내의 하위 서비스에서 Runtime Exception이 발생하면, 서비스를 호출한 최상위 Controller에서 해당 예외를 처리해준다.
- Global 레벨에서 처리
- 만약 여러 Controller에서 같은 Exception이 발생하는 경우엔 어떻게 해야 할까?
- 위의 방식처럼 Controller 별로 @ExceptionHandler 어노테이션이 붙은 메서드를 만들게 된다(유지보수성 증가, 중복 코드 양산)
- Spring에서는 이를 방지하기 위해 Web Application 전역적으로 @ExceptionHandler를 사용할 수 있도록 지원한다.
- @ControllerAdvice - Exception 처리 후 Error Page 등을 통해 처리가 가능하다
- ControllerAdvice를 사용하여 Exception 처리를 한 곳으로 모으는 경우, ResponseEntityExceptionHandler를 상속받도록 하여 Spring MVC에서 기본으로 제공되는 Exception들의 처리를 간단하게 등록할 수 있다. 각 Exception 처리를 위한 메서드들은 모두 protected로 선언되어 있으며, 하위 클래스에서 필요에 따라 Override 할 수 있다.

- @RestControllerAdvice
- REST API에 대한 Exception 처리 등에 용이. (Default 데이터를 리턴해 줄 수 있다.)
- @RestControllerAdvice = @ControllerAdvice + @ResponseBody

- @ControllerAdvice - Exception 처리 후 Error Page 등을 통해 처리가 가능하다
- @ExceptionHandler, @ControllerAdvice 클래스 내의 @ExceptionHandler 둘 중 뭐가 먼저 실행될까? 그리고 둘 다 실행 될까?
- @Controller내의 @ExceptionHandler로 예외처리를 하게 되면 거기서 예외처리가 끝난다. 더 상위로 Exception을 throw 하더라도@ControllerAdvice의 @ExceptionHandler에서 예외처리를 하지 않는다
- HandlerExceptionResolver를 이용한 처리
- Controller의 작업 중에 발생한 예외를 어떻게 처리할 지에 대한 전략이다
- DispatcherServlet내에서 예외 발생 시, resolverException 메서드를 구현한 HandlerExceptionResolver들이 실행 계획에 따라 처리되며 예외를 처리하게 된다.
- 사실 위에서 본 2가지 방식의 예외처리도 HandlerExceptionResolver를 이용한 예외 처리 방법이다
- Dispatcher Servlet에 기본적으로 3개의 HandlerExceptionResolver가 등록되어있다.
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- DefaultHandlerExceptionResolver
- ExceptionHandlerExceptionResolver
- Spring 3.2 때 AnnotationMethodHandlerExceptionResolver라는 이름으로 등장하였다.
- 현재는 Deprecated처리되어 ExceptionHandlerExceptionResolver 클래스를 사용하고 있다. 위에서 사용한@ExceptionHandler어노테이션에 대한 Resolver 클래스이다.
- ResponseStatusExceptionResolver
- ResponseStatusExceptionResolver는 예외에 대한 Http 응답을 설정해 줄 수 있다.
- 특정 예외가 발생하였을 때 , 단순히 500 (internal-server-error) 대신 더 구체적인 응답 상태 값을 전달해 줄 수 있다.

- DefaultHandlerExceptionResolver
- DispatcherServlet에 디폴트로 등록된 3가지 HandlerExceptionResolver에서 예외처리를 하지 못하는 경우, 마지막으로 DefaultHandlerExceptionResolver에서 예외처리를 해준다.
- DefaultHandlerExceptionResolver에서는 내부적으로 Spring 표준 예외처리를 해준다. 각 상황에 걸맞은 응답 코드를 리턴해 주는 역할을 한다.
- Request URL에 맞는 Controller를 못 찾는 경우 ==> 404 Not Found
- Controller 메서드 실행 중 예외가 발생하는 경우 ==> 500 Internal Server error
- Controller의 파라미터 형식이 잘못된 경우 ==> 400 Bad Request
Filter에서 발생한 예외 처리
- Web Application 레벨에서 처리를 해줘야 한다.
- filter에서 예외가 발생하면 여태까지 말한 예외처리 방법이 적용되지 않는다. 왜냐? 실제 Dispatcher Servlet에서 처리하기도 전에 예외가 발생되기 때문이다.
- web.xml에 error-page를 잘 등록해줘서 에러를 사용자에게 표현
- Filter 내부에서 try-catch 구문을 통해 예외 발생 시, request.getRequestDispatcher(String)를 통해 어떻게든 Controller까지 예외를 보내서 처리하게 한다.
Spring Handle Exception | Carrey`s 기술블로그
들어가며 Spring에서 제공하는 예외처리 방법에는 유용한 방법들이 몇가지 있다. Dispatcher Servlet내에서는 몇 가지 HandleExceptionResolver를 제공하여 예외 처리를 할 수 있도록 돕고 있다. 또한 @Controller
jaehun2841.github.io
참고 : https://exhibitlove.tistory.com/276
[spring boot] error 처리
출처 : velog.io/@leyuri/springboot-blog-project-72 @ControllerAdvice //어디에서 발생하던 간에 이쪽으로 오게 하기 위해서, 전역적으로 예외 처리 @RestController public class GlobalExceptionHandler { //..
exhibitlove.tistory.com
'스터디 노트 > 잡것' 카테고리의 다른 글
| 채널 (0) | 2022.12.12 |
|---|---|
| Patch Null 체크 (0) | 2022.06.29 |
| 트러블 슈팅 (0) | 2022.05.11 |
| 프로젝트에 도움이 되는 URL (0) | 2022.05.02 |
| Null Object pattern (0) | 2022.01.17 |