-
카테고리
-
세부 분야
백엔드
-
해결 여부
미해결
예상치못한 예외가 throw 되었을 경우의 Response 처리에 관련하여 질문드립니다
19.02.28 23:05 작성 조회수 235
2
실제로 컨트롤러에서 처리를 하다보면, 예상치 못한 에러가 발생하는 경우가 있는 것 같습니다. 가령 강의의 예제에서는 JSON serialization
, deserialization
과정에서 checked exception이 발생할수 있으며, Repository
객체를 사용하는 경우에는 DataAccessException
런타임 예외가 발생할 수 있을 것 같습니다. 이러한 경우들에도 적절한 응답을 돌려주고 싶은데, 그 때의 베스트 프렉티스에 대해서 여쭤보고자 합니다.
- 결국
@ExeptionHandler
라는 어노테이션이 붙은 메소드를 최소한 글로벌하게 하나는 만들어서 인터널 서버 에러(500)에 매핑시키게 되는 꼭 필요한 부분이라고 생각하는데, 맞는 생각일까요? 잘못하면 에러 로그를 view로 보여주게 될 것 같아서 그것을 방지하고자 함입니다. - 컨트롤러 내부에서도 결국 적어도 Unchecked Runtime Exception을 잡기 위해서
@ExceptionHandler
를 정의하면 컨트롤러별로 예상치 못한 예외를 적절히 핸들링해 필요한 처리를 할 수 있게 되기 때문에 정의하는 것이 좋을것 같다고 생각하는데요, 이렇게 정의 했을 때 제가 고민되는 부분이 있습니다. 예제에서 나오는 것처럼 로직으로 인해서 발생하는 에러는ResponseEntity
를 리턴하는 형태로 처리하고, 그 외의 에러는@ExceptionHandler
로 잡게되면, 에러를 2가지 서로 다른 방법으로 처리함으로서 코드의 가독성을 해치는게 아닐까라고 생각해 보았습니다. - 그렇다고
ResponseEntity
로 통일하고자하면, 컨트롤러 메소드 각각에서 반드시 return으로 예외를 처리해야 하기 때문에, 컨트롤러 메소드 마다 try catch로 감싸주고catch(Exception e)
같은 블록에서 반복적으로 internalServerError를 리턴해야만 하는 문제가 있습니다. - 그리고
@ExceptionHandler
로 통일하고자하면,throw
문을goto
처럼 사용하는 것이되어, 코드의 가독성을 해칩니다. 하지만 동시에 컨트롤러 메소드 내부의 if else를 줄여 줘서 가독성을 증가시키고, 컨트롤러 / 기타 빈 객체의 책임을 나누는 효과도 있습니다. 가령 service레벨이나 레포지토리 레벨에서 여러 데이터를 종합하다보니(MSA설계에서 자주 있는것 같습니다) 상황에 따라 200대가 아닌 리스폰스를 돌려줘야 할 필요가 있는 경우, 이것을 controller에서 호출한service.method()
의 리턴값으로 돌려줘서 컨트롤러에서 if else로 처리하게 되겠죠. 하지만 적절한 예외를 정의하여 그것을 컨트롤러가 아닌 webmvc빈에서throw
를 하여ExceptionHandler
가 처리하도록 하면, 컨트롤러 메소드 코드를 간결하게 할 수 있을 것 같습니다. 하지만 역시 throw 를goto
처럼 써서 가독성을 떨어뜨리는게 아닐까 하는 부담감이 있기도 하네요.
@ExceptionHandlerpublic void globalExecptionHandler(Exception e) {
return ResponseEntity.internalServerError();
}
이런 것들을 복합적으로 고민해서 어떻게 1) 예제처럼 간단하게 체크해서 발생시킬수 있는 에러 2) 복잡한 상황에서 컨트롤러 객체가 아닌 곳에서 확인할 수 있는 에러 3) 예상치못한 런타임 에러(Repository connection pool error, httpclient socket timeout ...)를 깔끔하게 처리하여 클라이언트에 돌려줄 수 있을지 고민입니다. 어떻게 하는게 베스트일까요?
답변을 작성해보세요.
2
백기선
지식공유자2019.03.01
애플리케이션 전반에 대한 에러는 언급하신대로 @ExceptionHandler를 만들어서 @ControllerAdvice안에 두고 글로벌 예외 핸들러를 쓰게 하는 것도 좋은 방법입니다.
하지만 특정 컨트롤러 로직(입력값 바인딩, 검증, 로직적인 검증)에서 발생하는 에러는 글쎄요. 그것도 뭔가 일반화 시켜서 공통적인 에러 핸들러로 처리할 수 있으면 좋긴하겠지만 그 컨트롤러에 특화된 로직이라면 그 위치에서 처리하는게 명시적이지 않을까 싶네요.
딱히 정해진 답이 없으니 여러 방법으로 해보시고 경험을 공유해 주시면 좋겠습니다.
좋은 질문 감사합니다.
0
답변 2