カスタムエラーの設定⚓︎
下記の手順では、 TypeScript 標準の Error 型の限界をカバーするために、業務例外を表現するための独自例外クラスを実装します。 加えて、 HTTP 通信に由来する業務例外について、外部ライブラリである Axios に直接依存せず、独自例外クラスに正規化してから扱うための設定例を示します。
カスタムエラーの必要性⚓︎
TypeScript には標準の Error 型が用意されていますが、一般に下記のような欠点があります。
-
主要なプロパティ(
name、message、stack)が、エラーの情報を型レベルで構造化して表現するには不十分です。たとえば HTTP ステータスコードやアプリケーション固有のエラーコードなどの情報を表現できません。 -
Error型に対してJSON.stringify()を実行した際に、name,message,stackがシリアライズされないため、ログ出力に必要な情報が欠落します。
これらの欠点をカバーするため、 Error 型を拡張して、業務例外を表す独自例外クラス(カスタムエラー)を実装する必要があります。
他方で、OpenAPI 仕様書からのクライアントコード生成 で導入した Axios には、 HTTP 通信で発生するエラーを表現するために、 Error 型を拡張した AxiosError 型が用意されています。 AxiosError 型には、リクエスト設定 ( config )、レスポンス ( response )、エラーコード ( code ) などが含まれ、 toJSON() メソッドでこれらを JSON 形式に変換できます。 AxiosError の一般的な構造については、 Axios 公式ドキュメントの Handling Errors を参照ください。
エラーハンドリングに AxiosError 型をそのまま用いることも考えられますが、業務例外の構造が直接外部ライブラリに依存しないクリーンなコードを保つため、 AxiosError 型をカスタムエラーへ変換します。
業務例外の表現方法として、 業務例外が発生する可能性のある関数の戻り値を Result 型で表現し、Error 型の throw を避ける方法も考えられます。 しかし、例外処理方針 - フロントエンドの例外処理方針 で述べたように、 try-catch を用いてハンドリングします。
カスタムエラーを定義する⚓︎
標準の Error 型を拡張して、カスタムエラーの基底クラスとなる抽象クラスを実装します。 これを継承するカスタムエラーの具象クラスには、ログ出力に必要な情報を取り出すために、 toJSON() メソッドの実装を強制します。
| カスタムエラーの基底クラス | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 | |
HTTPError クラスの定義⚓︎
CustomError クラスを拡張して、 HTTP 通信に起因する業務エラーを定義します。
集約例外ハンドラーの設定 で設定した通り、バックエンドから返却されるエラーレスポンスには、 ProblemDetails に基づくレスポンスボディーを含みます。 よって、 HTTP 通信によって発生しうるエラーを表す HttpError クラスには、AxiosError.response.data を経由して ProblemDetails の情報を格納します。
例外処理方針 - API 通信のエラーレスポンス で述べているように、拡張メンバー exceptionId と exceptionValues を追加で定義しています。
加えて、これらの情報を構造化して出力できるように、 toJSON() メソッドを実装します。
| 基底クラスを継承した HttpError クラスの例 | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
| ProblemDetails の型定義 | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
HTTPError の具象クラスの定義⚓︎
HttpError を継承して、 発生しうるエラーを表現する具象クラスを定義します。 バックエンドアプリケーションから連携された OpenAPI 定義書に従って、 必要な具象クラスを定義してください。 下記の例は、 HTTP ステータスコード 404 Not Found に対応する具象クラス NotFoundError の実装例です。
| HttpError を継承した具象クラスの例 | |
|---|---|
1 2 3 4 5 6 | |
AxiosError をカスタムエラーに変換する⚓︎
Axios の Interceptors を用いて、 AxiosError をカスタムエラーに変換します。 Axios の Interceptors は、 HTTP リクエストおよびレスポンスが処理される前に、任意のハンドリング処理を挟み込んで実行できる機能です。
この機能を用いて、 HTTP ステータスコードに対応した適切なカスタムエラーへ変換する処理を一箇所に集約して実装します。 HTTP ステータスコードは AxiosError の response.status へ格納されています。
axiosInstance.interceptors.response の実装例を下記に示します。 たとえば下記の例では、response.status が 404 である AxiosError を、NotFoundError に変換して返却しています。
| サンプルアプリケーションの Interceptors の実装例 | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
業務例外が発生しうる処理の呼び出し⚓︎
業務例外が発生する可能性のある処理の呼び出し時は、try-catch で囲みます。 例外を catch したら、 instanceof を使用して、どのカスタムエラーに該当するか検出し、検出したエラーに応じた処理を実行します。 下記は API の呼び出しで NotFoundError が発生した場合に、ユーザーへトースト通知し、別画面へ遷移する例です。
| サンプルアプリケーションの実装例 | |
|---|---|
1 2 3 4 5 6 7 8 9 10 | |