TIL,WIL(일간,주간 회고)

[TIL][트러블 슈팅][rxjs]에러 처리

worldint 2024. 6. 22. 21:35

회사에서 rxjs를 사용하는 부분이 있는데
pipe안에 여러개의 concatMap을 사용중이고

rxjs를 사용하는 함수가 아래 코드처럼 try catch로 감싸져있어서

try{
  funcA() //rxjs사용 함수
}catch(e){
    throw new InternalServer에러(e)
}

함수에서 에러가나면 throw로 잘 던지고 있는줄 알았는데

서버 crash나고 있었음 (pm2로 금방 다시 시작은 됨)

확인해보니 rxjspipe내부에서 발생한 에러는

try catch에서 잡히지 않음

try {
  const source$ = rxjs.of(1, 2, 3);
  const mapped$ = source$.pipe(
    rxjs.operators.map(value => {
      if (value === 2) {
        throw new Error("Something went wrong!");
      }
      return value;
    })
  );

  mapped$.subscribe(value => console.log(value));
} catch (error) {
  console.log("Caught an error:", error);
}

이런 코드가 있을 때
value변수에 1,2,3 차례로 값이 들어가게 되고
2의 차레에서 throw로 에러가 발생해 catch로 갈 것 으로 예상되지만

subscribe 메소드는 즉시 반환됨
그니까 저 위에 pipe내부에 작성한 코드들은 subscribe()를 호출했을때 부터 동작을 하는데
subscribe는 호출 즉시 끝나고 저 pipe부분의 동작만 따로 비동기적으로 돌고 있는 그런 개념임

그래서 try부분의 코드가 이미 다 끝난 뒤에 나온 에러이기 때문에 try catch에서는 잡을수 없고
따로 rxjs에서 에러처리하는 방식으로 처리를 해야한다

const items$ = from(items).pipe(
    concatMap((item) => {
      //-----생략
      return of(item);
    }),
    catchError((err) => {
      return throwError(() => err);
    }),
  );

  items$.subscribe({
    next: (val) => {
      myArr.push(val);
    },
    error: (err) => {
      console.log(err);
    },
  });

pipe에 catchError를 통해서 에러를 던져주고
그걸 subscribe에서 저렇게 처리를 하면된다