05
第 5 章

エラーハンドリングと縮退設計

この章で学ぶこと
1 バックエンド API障害時の波及を防ぐ縮退設計
2 Promise.allSettled による個別の成功・失敗判定
3 タイムアウトとフォールバックの組み合わせ
4 サーキットブレーカによる障害サービスの遮断
図解

この章で扱う範囲

BFF とバックエンド API間の障害対処がこの章の対象範囲

章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
解説

並列呼び出しでエラーハンドリングしないとどうなるか

エラーハンドリングの欠如
並列呼び出しで1つが失敗すると、成功した結果も含めて全体がエラーになる
実害
通知サービス1つの障害で、取得済みのプロフィール・注文履歴も破棄され、画面全体が表示不能になる
ch05-error-handling/src/app.js
const [profile, orders, notifications] = await Promise.all([  fetchProfile(userId),  fetchOrders(userId),  fetchNotifications(userId), // ← ここが失敗すると全体がエラー]);
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
コード

個別に成功・失敗を判定する設計

設計上のあるべき姿 — 各サービスの成功・失敗を個別に判定し、失敗した部分だけを代替値に置き換える

Promise.allSettled を使うと、すべての完了を待ちつつ個別の結果を受け取れる

ch05-error-handling/src/app.js
const results = await Promise.allSettled([  fetchProfile(userId),  fetchOrders(userId),  fetchNotifications(userId),]);// results[0] = { status: \"fulfilled\", value: {...} }// results[2] = { status: \"rejected\", reason: Error }
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
図解

Promise.all と Promise.allSettled の挙動の対比

1つの Promise が失敗したときの挙動の違い

章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
解説

縮退設計とは

縮退(Graceful Degradation)
一部の障害時に、残りの正常な部分で機能を提供し続ける設計
フォールバック
障害時に本来の値の代わりに返す代替値(空配列・空オブジェクトなど)
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
図解

縮退レスポンスの流れ

障害サービスの部分を代替値で埋めた縮退レスポンスの流れ

章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
コマンド

docker compose up

実行するコマンド

terminal
$ cd ch05-error-handling$ docker compose up -d
ch05-error-handling — この章のサンプルコードのディレクトリ
docker compose up -d — 4 つのコンテナをバックグラウンドで起動

※ Windows(PowerShell)では curl を curl.exe に読み替えてください

章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
実演

縮退レスポンスの実演(全サービス稼働時)

目的全サービス稼働時のレスポンスを確認する
実行する
コマンド
$ curl \"http://localhost:3000/api/dashboard?userId=1\"
※ Windows(PowerShell)では curl を curl.exe に読み替えてください
確認する
ポイント
profile・orders・notifications の3つすべてにデータが含まれること
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
図解

この章のアプリ構成(再掲)

BFF とバックエンド API間の障害対処がこの章の対象範囲(再掲)

章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
実演

縮退レスポンスの実演(通知サービス停止時)

目的通知サービス停止時に縮退レスポンスが返ることを確認する
実行する
コマンド
$ docker compose stop notification$ curl \"http://localhost:3000/api/dashboard?userId=1\"
※ Windows(PowerShell)では curl を curl.exe に読み替えてください
確認する
ポイント
notifications が空配列になり、profile と orders は正常値のままであること
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
コード

縮退レスポンスの実装

Promise.allSettled の結果から成功・失敗を判定し、失敗時は代替値を返す

ch05-error-handling/src/app.js
const profile =  results[0].status === \"fulfilled\"    ? results[0].value    : { name: \"\", email: \"\" };const orders =  results[1].status === \"fulfilled\" ? results[1].value : [];const notifications =  results[2].status === \"fulfilled\" ? results[2].value : []; res.json({ profile, orders, notifications });
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
解説

タイムアウト

タイムアウト
バックエンド APIへのリクエストに制限時間を設け、時間内に応答がなければ中断する仕組み
遅い障害への対処
サービスが停止せず応答が遅くなる場合、接続エラーが発生しないため待ち続けてしまう
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
解説

サーキットブレーカとは

サーキットブレーカ
呼び出しの失敗を監視し、連続した障害を検知したら自動的に回路を遮断する仕組み
語源
電気回路のブレーカと同じ考え方。過電流が流れると回路を切り、機器を保護する
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
図解

BFF におけるサーキットブレーカ

サーキットブレーカの3つの状態と遷移

章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
コード

fetchWithTimeout の実装

AbortSignal.timeout で制限時間を設定する fetch のラッパー関数

ch05-error-handling/src/app.js
async function fetchWithTimeout(url, timeoutMs = 3000) {  const response = await fetch(url, {    signal: AbortSignal.timeout(timeoutMs),  });  return response.json();}
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
実演

タイムアウトによる縮退の実演

目的遅延を注入した通知サービスに対してタイムアウトが発動し、フォールバック値が返ることを確認する
実行する
コマンド
$ docker compose stop notification
bash / zsh:
$ DELAY_MS=5000 docker compose up -d notification
PowerShell:
$ $env:DELAY_MS="5000"; docker compose up -d notification
$ curl \"http://localhost:3000/api/dashboard?userId=1\"
※ Windows(PowerShell)では curl を curl.exe に読み替えてください
確認する
ポイント
3秒程度でレスポンスが返り、notifications が空配列になること
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ
まとめ

この章のまとめ

縮退設計により、1つのバックエンド APIの障害が画面全体に波及することを防げる
Promise.allSettled は各 Promise の成功・失敗を個別に判定できる
タイムアウトにより、遅いバックエンド APIを一定時間で切り離せる
縮退設計は障害時だけでなくタイムアウト時にも発動し、フォールバック値で障害部分を埋める
サーキットブレーカは失敗が続くサービスへのリクエストを一時的に遮断する
次章: BFF と API Gateway の責務の分離
章の位置づけ
縮退設計
縮退の実演
タイムアウトと補強
タイムアウトの実演
まとめ