🤧

Angular(RxJS)のエラーハンドリングで使ってるオペレータたち

2024/09/15に公開

AngularでRxJSを用いてエラーハンドリングする時によく使うものをまとめ。

subscribeのコールバックたち

of(1,2,3).subscribe({
  next: (res) => console.log(res),
  error: (e) => console.error(e),
  complete: (res) => console.log(res)
})
  • next
    Observableが新しい値を発行するたびに呼び出される
  • error
    Observableがエラーを発行した時に呼び出される。
  • complete
    Observableが完了した時に一度だけ呼び出される。ストリームが正常に終了したことを示す。

下記のように何も指定しないとnextが呼ばれる。

of(1,2,3).subscribe((res) => console.log(res));

エラーハンドリングでよく出るオペレータ

  • catchError
    ストリームを流れてきたエラーをキャッチする。
    新しいObservableかErrorを返さなければいけない。
  • throwError
    Observable内でエラーを発行し、catchErrorオペレータに伝達する。
    catchErrorがなければ、subscribeのerrorコールバックを呼び出してストリームをエラー終了させる。
  • EMPTY
    完全に空のObervableを生成する。
    すぐにsubscribeのcompleteコールバックが呼び出され、ストリームを完了させる。

catchErrorした際になにを返そうか

catchエラー内でthrowErrorすると再度errorオブジェクトがストリームを流れ、次のcatchErrorまたはsubscribeのerrorコールバックまで流れる。

of(1,2,3)
  .pipe(
    map((n) => {
      if (n === 3) throw 'three!';
      return n;
    }),
    catchError((error) => {
      console.log('catchError');
      // errorをerrorのまま返す
      return throwError(() => e);
    })
  )
  .subscribe({
    next: (res) => console.log(res),
    error: (e) => console.error(e),
    complete: () => console.log('complete')
  });

// 1
// 2
// catchError
// three!

catchError内でObservableを返すと、通常通りsubscribeでnextとcompleteが呼ばれる。

of(1,2,3)
  .pipe(
    map((n) => {
      if (n === 3) throw 'three!';
      return n;
    }),
    catchError((error) => {
      console.log('catchError');
      // errorをただのobservableに変更
      return of(error);
    })
  )
  .subscribe({
    next: (res) => console.log(res),
    error: (e) => console.error(e),
    complete: () => console.log('complete')
  });

// 1
// 2
// catchError
// next three!
// complete

EMPTYを返すと即時にsubscribeのcompleteが呼ばれる。

of(1,2,3)
  .pipe(
    map((n) => {
      if (n === 3) throw 'three!';
      return n;
    }),
    catchError((error) => {
      console.log('catchError');
      // errorをEMPTYにして返す
      return EMPTY;
    })
  )
  .subscribe({
    next: (res) => console.log(res),
    error: (e) => console.error(e),
    complete: () => console.log('complete')
  });

// 1
// 2
// catchError
// complete

Discussion