내가 코드를 작성할 때는 파일 시스템은 안정적이며 네트워크는 원활하게 연결되어 있으며 JVM이 차지하는 메모리는 여유있는 이상적인 상황을 가정한다.
이를 일컬어 Happy Path 라고 말하는 것 같은데, 소위 말하자면 머리가 꽃밭에 있어서 아무 걱정이 없는 상태다.
그러나 소프트웨어는 단지 현실의 문제를 가상화한 모델링 결과일 뿐이다.
현실은 더욱 복잡하고 가차없으며 저렇게 작성했던 내 과거의 코드들은 무분별하게, 잔인하게, 야만적인 느낌이 들 만큼 Exception(예외)을 뿌려주었다.
연결된 네트워크 이상으로 전달이 지연되거나 실패하는 경우, 갑작스런 접속자 폭증으로 응답이 지연되는 경우 등은 기본.
사전에 공유된 내용도 없이 인터페이스 내용이 바뀐다거나 기준 정보가 변경되는 경우도 배제할 수 없다.
결국... 유비무환(有備無患)이다.
수많은 다이어그램들이 소프트웨어 설계의 결과라고 한다면, 예외 처리 코드는 운영자의 경험과 고민의 결과라고 생각한다.
감사합니다 @ControllerAdvice
@ControllerAdvice 어노테이션을 가진 클래스는 @Controller 클래스들에 공유되며,
@ExceptionHandler, @InitBinder, @ModelAttribute 를 구현하는 @Component 어노테이션의 구현체가 된다.
간단하게 얘기하자면 아래 코드는 이제 모든 컨트롤러 클래스들에 공유된다.
@ControllerAdvice
public class SampleExceptionController {
@ExceptionHandler
protected ResponseEntity<String> exceptionHandlerExample(RuntimeException e){
return ResponseEntity.ok(e.getMessage());
}
}
그렇기 때문에 어떤 컨트롤러에서든 RuntimeException 예외가 발생하면 이 @ExceptionHandler 위치한 메소드로 넘어와 하기 동작을 수행한다.
대표적인 예외 타입들을 묶어 표현해 놓으면 나름대로 안정적으로 동작하는 모습을 볼 수 있게 해준다.
물론! 여기에 만족하면 큰일난다.
@ControllerAdvice 사용할 때 놓치지 않아야 할 간단한 실험
만약 아래와 같이 RuntimeException 예외를 인자로 받는 핸들러를 하나 더 만들어 본다면 어떻게 될까?
@ControllerAdvice
public class SampleExceptionController {
@ExceptionHandler
protected ResponseEntity<String> exceptionHandlerExample(RuntimeException e){
return ResponseEntity.ok(e.getMessage());
}
@ExceptionHandler
protected ResponseEntity<String> exceptionHandlerExample2(RuntimeException e){
return ResponseEntity.ok(e.getMessage());
}
}
Ambiguous @ExceptionHandler method mapped for... 이란 메시지를 뱉어내며 빌드가 되지 않는다.
RuntimeException 관련 예외를 모두 한 번에 처리해주기 때문에 편리하지만, 만족하지 않고 조금 더 세분화하려는 노력이 필요하다.
한 개 클래스 내에서 같은 인자를 받는 경우를 실험해봤다면, 두 개 이상을 클래스에서 같은 인자를 받는 실험은 어떻게 동작할까?
만약 서로 동시에 2개 클래스에서 @ControllerAdvice 어노테이션을 가진 상태에서 RuntimeException 예외를 인자로 받는다면?
예상외로 이러한 유형의 중복 선언은 앞선 케이스와 달리 정상적으로 빌드된다.
와 그럼 그냥 써도 되겠다.
안 된다.
그치만 둘 중 어떤 것에서 에러를 처리하는지 알 수 없기 때문에 덕지덕지 예외를 바르다 보면 디버깅에 난항을 겪을 것이 분명해 보인다.
추천하는 글
이 링크에 상세한 내용들이 많이 정리되어 있다.
- Throwable, Exception, Error, RuntimeException 등 모호했던 개념들을 예시와 함께 설명
- 예외를 발생시키는 방법과 처리하는 방법
- 예외 처리에서 피해야 할 패턴 (Anti-pattern)
'Backend > Spring' 카테고리의 다른 글
[Spring] Proxies in JPA (0) | 2023.05.30 |
---|