1実行順の全体マップ
ここまで学んだ全部品を1枚にまとめた実行順マップです。リクエストは必ずこの順で部品を通り、レスポンスはインターセプターの後処理を経て返る、というコース全体の総まとめになります。
// 1リクエストが通る道(上から順に実行される)
//
// クライアント
// │
// ▼
// ① ミドルウェア … ルーティング前の共通処理
// ② ガード … 通してよいか判定(拒否なら 403)
// ③ インターセプター(前) … ハンドラ前の割り込み
// ④ パイプ … 値の変換と検証(失敗なら 400)
// ⑤ ハンドラ … コントローラのメソッド本体
// ⑥ インターセプター(後) … 戻り値の加工
// │
// ▼ レスポンス
//
// ※ どの段階で例外が投げられても、最後は例外フィルタが受け止める
2実行順をログで確かめる
ミドルウェアからインターセプターの後処理までの6段階を関数の入れ子で再現し、実行順をログで確かめる例です。インターセプターだけが「前」と「後」の2回登場する、という非対称な構造が一目で分かります。
TypeScript
3弾かれた場所より内側は動かない
ガードやパイプで弾かれたとき、それより内側の部品が一切実行されないことを整理した例です。実行されなかった部品からエラーの発生段階を逆算する、というデバッグの基本動作につながります。
// 途中で弾かれると、それより内側は一切実行されない
//
// ケースA: ガードが false を返した場合(403)
// ミドルウェア → ガード ✕
// → インターセプターもパイプもハンドラも動かない
//
// ケースB: パイプが検証エラーを投げた場合(400)
// ミドルウェア → ガード → インターセプター(前) → パイプ ✕
// → ハンドラは動かない
// → インターセプターの「後処理」も実行されない点に注意
//
// 「DB アクセスのログがない = ハンドラの手前で弾かれている」
// のように、実行されなかった部品から原因の段階を逆算できる
4正常系と異常系の2つの出口
どの段階の例外も最終的に例外フィルタへ集まる、というレスポンスの出口の整理です。正常系の出口はインターセプターの後処理、異常系の出口は例外フィルタという2系統を区別すると、実務での混乱が解消します。
// どの段階の例外も、最終的に例外フィルタへ集まる
//
// ガードの例外 ─┐
// パイプの検証エラー ─┤
// ハンドラ内の例外 ─┼──▶ 例外フィルタ ──▶ エラーレスポンス
// インターセプターの例外 ─┘
//
// つまりレスポンスの出口は2系統ある:
// 正常系 … ハンドラ → インターセプター(後) → クライアント
// 異常系 … 例外発生 → 例外フィルタ → クライアント
//
// 「エラーレスポンスの形を変えたいのにインターセプターを
// 直しても効かない」という実務の混乱はこの図で解消できる
5デバッグの切り分けチェックリスト
「API が期待通り動かない」ときに原因の層を特定する実務チェックリストです。ライフサイクルの順序を知っていれば、ステータスコードとログの出どころだけで5問の質問に答える形で原因を絞り込めます。
// 「API が期待通り動かない」ときの切り分け手順
//
// Q1. ミドルウェアのアクセスログは出ているか?
// → 出ていない: リクエスト自体が届いていない
// (URL・ポート・CORS を確認)
// Q2. 403 が返っていないか?
// → ガードで弾かれている(トークン・権限を確認)
// Q3. 400 が返っていないか?
// → パイプの検証で弾かれている
// (DTO と実際のリクエストボディを見比べる)
// Q4. ハンドラ内のログは出ているか?
// → 出ているのにレスポンスが変:
// インターセプター(後)の加工を疑う
// Q5. 500 が返っていないか?
// → ハンドラ以降の例外。例外フィルタのログで原因を特定
//
// 順序を知っていれば、この5問だけで原因の層を特定できる