[NEST] guard에서의 error는 interceptor에 왜 안잡힐까?

김지원·2022년 10월 23일
0

nest

목록 보기
2/4

이 내용이 나온 이유

api 요청 시 header에서 필수로 받아야하는 값이 db로 정리되어있어 service를 di받아야하기 때문에
guard를 이용해 validation을 해주려고 했습니다.

하지만 guard에서 사용자 정의 에러를 던지니 interceptor를 들리지않고 바로 예외 filter로 넘어가게 되었고 멘붕이 왔어요~

마음 다잡고 이제 왜 그렇게 되었는지 설명하면서 nest의 요청 수명 주기에 대해 알아보도록 하겠습니다.


nestjs의 요청 수명 주기

nest 공식페이지를 보면 이렇게 적혀 있는 것을 볼 수 있습니다

요청 -> 미들웨어 -> 가드 -> 요청 인터셉터 -> 파이프 -> 응답 -> 응답 인터셉터 -> 예외 필터 -> 응답

이것만 보면 당연히 인터셉터도 들리는게 맞다! 라고 생각할 수 있습니다.
왜냐? catchError로 error를 잡으니까!!

물론 저도 그랬습니다ㅠㅠㅠㅠㅠ

그래서 guard와 interceptor, filter에 로그를 찍어봤습니다

그 결과..

인터셉터만 쏙 빼두고 응답을 주고 있는것을 볼 수 있습니다ㅠ

물론 guard도 middleware의 한 종류니까 middleware 자체도 안되겠죠? (해본건 안비밀..)

왜 그런걸까요?

냅다 스택 오버 플로우를 들어가봤습니다

https://stackoverflow.com/questions/61087776/interceptor-not-catching-error-thrown-by-guard-in-nestjs

위 글에서는.. '안돼 돌아가! 잡을 수 없어' 였습니다

그럼 다시 생각해봅시다 왜 인터셉터만 쏙 빼두고 갈 수 있을까요?

제가 생각한 이유는 이렇습니다

interceptor에서 사용하는 rxjs의 catchError자체가 응답 후의 error를 잡게 되는 것이고
middleware와 guard는 controller에 들어오기 전에 실행되기 떄문에 interceptor에서는 catch 할 수 없다!

이것을 증명하기 위해 이번에는 정상적으로 controller에 들어온 후 에러를 터트리고 로그를 찍어보았습니다.

정상적으로 interceptor에 들리고 에러를 잡아 로직을 처리하는 것을 보았습니다.

그리고 다음 nestjs의 issues를 보면

https://github.com/nestjs/nest/issues/3065

guard가 interceptor보다 먼저 실행되기 때문에 guard의 error는 잡을 수 없다라고 설명하고 있습니다.


그럼 우리는 어떻게 해야될까요?

어떻게든 돌아가야합니다..

error & log 처리를 interceptor가 아니라 filter를 이용한다던지

db의 값이나 다른 service를 이용해 확인을 해야한다면 service단에서 해결하거나

아니면 guard에서 모든 것을 해결하는 방법 등 여러가지 방법이 있을 것 같습니다.

이 이슈는 나중에도 또 발목을 잡게 될 것 같은데 저같은 이슈가 있으신분들에게 조금이라도 도움이 됐음 합니다ㅎㅎ

여담으로 저는 interceptor에서 사용량과 성공 여부를 체크하는 로직이라서
guard에서 error가 나면 어떤 사람이 사용한지 몰라 interceptor에서 할 일이 없어 그대로 두었습니다


결론

가드 & 미들웨어에서 사용자 정의 에러를 던지면 interceptor를 들리지 않는다!

profile
backend-developer

2개의 댓글

comment-user-thumbnail
2022년 12월 14일

저도 Interceptor 로 Logging Interceptor 를 만들던 중에 "라이프 사이클에 따르면 Guard 에서 에러가 발생했을 떄, Interceptor 로 가지 않지 않을까?" 라는 의구심이 들어서 찾아보던 중에 딱 맞게 오게되었습니다.
이런 부분들을 대신 연구해주셔서 큰 도움이 되었습니다. 감사합니다.

1개의 답글