• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

ExceptionHandler와 BasicErrorController에 대한 궁금증

23.07.22 23:46 작성 조회수 286

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 

[질문 내용]
안녕하세요. 강의를 듣던 도중 궁금한 점이 생겨 질문을 남겨 봅니다.
API 예외를 처리할 때는 ExceptionHandler를 사용하여 처리하고,
HTML 화면을 제공할 때 예외 처리는 BasicErrorController를 사용하는게 편하다고 강의에서 말씀해주셨는데요

@Controller
@Slf4j
public class TestErrorController {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public ErrorResult IllegalArgumentException(IllegalArgumentException e) {
        log.info("IllegalArgumentException ", e);

        return new ErrorResult("BAD Argument", e.getMessage());
    }

    @GetMapping("/test/error/{id}")
    public String testException(@PathVariable String id) {
        if (id.equals("bad")) {
            throw new IllegalArgumentException("bad argument");
        }
        return "home";
    }

    @GetMapping("/test/error2/{id}")
    @ResponseBody
    public String testException2(@PathVariable String id) {
        if (id.equals("bad")) {
            throw new IllegalArgumentException("bad argument");
        }
        return "OK";
    }

}

위와 같이 RestController가 아닌 Controller에서
View를 반환해주는 메서드가 있고, HTTP 메시지바디에 문자열을 반환해주는 메서드가 있는 상태에서
API 예외를 처리하는 @ExceptionHandler를 작성 하였고 테스트를 위해

/test/error/bad, /test/error2/bad를 호출해보면 둘 다 @ExceptionHandler가 예외를 처리하여 JSON 문자열이 반환되어 지더라구요..

여기서 궁금점이 생기게 되었는데요

  1. 위와 같이 하나의 컨트롤러에서 View를 반환해주었을 때 IllegalArgumentException이 발생했다면 BasicErrorController처럼 오류페이지를 반환하고,
    API 의 경우 IllegalArgumentException이 발생하면 @ExceptionHandler에서 처리를 할 수 있는 방법은 없는 걸까요??

  2. 만약 위의 질문에 대한 답이 없다 라고 한다면 실무에서 개발 설계를 할 때, API 컨트롤러와 View를 반환해주는 컨트롤러를 분리하여 설계를 하나요?

답변 1

답변을 작성해보세요.

1

y2gcoder님의 프로필

y2gcoder

2023.07.24

안녕하세요. 박성환님, 공식 서포터즈 y2gcoder입니다.

 

@ExceptionHandler는 해당 애노테이션이 위치한 컨트롤러에서 대상 예외가 발생했을 때 처리하게 됩니다. 그래서 아마도 위에서 말씀하신대로 모두 API 예외 응답으로 처리된 것 같습니다. API 예외 처리 - @ExceptionHandler 챕터부터 강의 자료와 함께 차근차근 수강하시면 아마 이해하실 것 같습니다 :)

그리고 보통 실무에서는 API 컨트롤러와 View를 반환하는 컨트롤러를 분리하여 개발하는 것이 일반적입니다. 두 컨트롤러는 보통 요청과 응답을 제공하는 것에 있고 그 방식이 다르기 때문에 서로 분리해서 개발하는 것이 유지보수나, 책임 분리에 좋다고 생각합니다.

만약 위의 구조에서 API 컨트롤러와 뷰 컨트롤러에 따라 응답을 처리하고 싶다면 방법은 있습니다. @ExceptionHandler가 붙은 메서드에서 HttpServletRequest를 파라미터로 받고, getHeader()를 이용해서 Accept 헤더를 조회하여 Accept 헤더 타입에 따라 json 응답과 View 응답을 분기처리 해주시면 됩니다. 다만 이 부분은 컨트롤러 분리보다 훨씬 더 비효율적인 처리라 생각하기 때문에 추천하지는 않습니다 :)

감사합니다.

박성환님의 프로필

박성환

질문자

2023.07.24

말씀하신 @ExceptionHandler에서 분기를 처리하는 것은 좋은 방법 같지는 않아
API 컨트롤러와 View를 반환하는 컨트롤러를 분리하여 개발하는 방법을 활용하는게 좋을꺼 같네요!

답변 덕분에 궁금증이 해결 되었습니다!! 감사합니다!

y2gcoder님의 프로필

y2gcoder

2023.07.24

파이팅입니다!