자바에서는 try/catch, throw 구문을 활용해 예외처리를 했지만 스프링부트에서는 더 편리하게 예외처리 기능을 제공한다.
개발자가 직접 처리할 수 있는 것으로 코드 설계를 통해 처리할 수 있다.
자바의 가상머신에서 발생시키는 것으로 OutOfMemory, StackOverFlow 등이 있어 개발자가 실질적으로 처리할 수 있는 것이 없다.
자바의 예외 클래스
모든 예외 클래스는 Throwable 클래스를 상속 받으며 Exception 클래스는 다양한 자식 클래스를 가지고 있다.
상황을 파악해서 문제를 해결하는 방식
예외가 발생할 수 있는 구문은 try 블록에 작성하며 catch 구문에는 예외처리 내용 작성
이 때 catch 블록은 여러개 작성할 수 있다.
예외가 발생한 메서드를 호출한 곳에서 에러 처리를 할 수 있게 전가하는 방식
throw 키워드를 사용해 어떤 예외가 발생했는지 내용을 전달할 수 있다.
예외 발생 시 호출부로 예외 내용을 전달하면서 적합한 예외 타입으로 전달
외부에서 들어오는 요청에 담긴 데이터를 처리하는 과정에서 예외 발생 시 예외를 복구하기보다는 어떤 문제가 발생했는지 클라이언트에게 상황을 전달하는 경우가 많다.
예외 발생 시 오류메시지를 전달하려면 각 레이어의 예외를 컨트롤러로 전달해야 한다.
해당 방식은 범위를 설정하지 않을 시 전역 범위에서 예외를 처리한다.
RestControllerAdvice 예외처리 실습
컨트롤러 클래스에 @ExceptionHandler를 사용한 메서드를 선언하면 해당 클래스에 국한해서 예외처리가 가능하다.
컨트롤러 내 @ExceptionHandler 사용
@ControllerAdvice와 컨트롤러 내에 같은 예외처리를 할 시 우선순위가 높은 클래스 내 핸들러 메서드가 사용되는 것을 확인할 수 있다.
Exception.class
@ControllerAdvice
@ExceptionHandler(Exception.class)
NullPointerException.class
@ControllerAdvice
@ExceptionHandler(NullPointerException.class)
@ControllerAdvice 클래스 내 동일 핸들러 메서드가 선언된 상태라면 더 구체적인 exception 클래스가 지정된 쪽이 우선순위를 갖는다. Exception보단 NullPointerException이 더 구체적이기 때문에 NullPointerException이 우선 순위를 가짐
글로벌 예외 처리와 @Controller 내 동일 예외처리 시 범위가 좁은 컨트롤러의 핸들러 메서드가 우선 순위를 가짐
표준 예외만 사용해도 대부분 상황이 해결 가능하다.
그럼에도 커스텀 예외 사용하는 이유는 네이밍에 개발자의 의도를 담을 수 있어서 예외상황을 짐작하기 쉽기 때문이다.
또한 예외를 개발자가 관리하기 수월해진다. 표준 예외를 상속 받은 커스텀 예외들은 개발자가 직접 코드로 관리할 수 있기 때문
커스텀 예외로 관리 시 의도하지 않은 예외는 개발자의 코드가 처리하지 않기 때문에 혼동 여지가 줄어든다.