SDDにおけるエラーハンドリング仕様の書き方

エラー処理は実装ではなく「仕様」の中心に置く

SDD(仕様駆動開発)で最も軽視されやすく、そして最も重要な領域があります。
エラーハンドリングです。

多くの開発では、エラー処理は実装の後半に書かれます。

  • とりあえず例外を投げる
  • 失敗したらメッセージを出す
  • ログを残す

しかしSDDの観点では、これは順序が逆です。
エラーハンドリングは付属処理ではありません。
システムが何を保証するかを定義する仕様です。

成功時の挙動だけを仕様にしても、ソフトウェアの振る舞いは決まりません。
現実のシステムは、むしろ失敗時にこそ振る舞いが問われます。

なぜエラー仕様が必要なのか

次の問いに答えられるでしょうか。

「処理が途中で失敗したとき、システムはどの状態になるか」

これが未定義のままでも、プログラムは動きます。
しかし、安定はしません。

例えば注文処理。

  • 決済成功
  • 在庫更新失敗

このとき、

  • 注文は成立するのか
  • 返金するのか
  • 再試行するのか

これは実装判断ではありません。
仕様です。

エラー仕様がない状態とは、
「障害時の挙動を開発者が都度決めるシステム」
を意味します。

よくある誤解

「エラーは想定外だから、仕様化できない」

逆です。
想定外のものは仕様にできません。
しかし、ほとんどのエラーは想定内です。

例:

  • 入力不正
  • 権限不足
  • 外部API障害
  • タイムアウト
  • 同時更新

これらは発生確率が高い現象です。
仕様化しない方が不自然です。

エラーの分類

まずエラーを分けます。
SDDではここが重要です。

1. 業務エラー(Business Error)**

  • 在庫不足
  • 上限超過
  • 重複登録

これは失敗ではなく、許可されない操作です。
例外ではありません。

2. システムエラー(System Error)**

  • DB接続失敗
  • APIタイムアウト
  • 内部例外

これは処理失敗です。

この2つを区別しないと、UI・API・ログが破綻します。

仕様として書くべき内容

最低限、次を定義します。

  • 失敗時の状態
  • 再試行の可否
  • 利用者への通知
  • ロールバック範囲
例:支払い処理
状況 システム状態 利用者表示
カード拒否 未注文 再入力
決済成功・在庫失敗 未確定 処理中表示
通信断 不明 保留表示

ここまで書いて初めて、振る舞いが決まります。

テストとしてのエラー仕様

SDDでは、これをテストにします。

  • 在庫不足なら注文生成されない
  • タイムアウトなら確定しない
  • 再試行で成功する

成功ケースより先に、失敗ケースのテストを書きます。
これにより、例外処理が設計になります。

API設計との関係

エラー仕様が曖昧だと、APIが壊れます。

悪い例:

  • 200と500しかない
  • メッセージ文字列だけ

良い例:

  • 409:業務競合
  • 422:入力不正
  • 503:外部依存失敗

コードと状態を対応させます。
クライアントはこれで挙動を決定できます。

注意点 ― 例外を握りつぶさない

ありがちな実装があります。

「とりあえず成功扱いにする」

これは短期的には安定します。
長期的にはデータ不整合になります。

仕様で決めるべきは、
失敗を隠すかではなく、
失敗をどう扱うかです。

まとめ ― 安定するシステムは失敗時に決まる

多くの仕様書は、成功時の流れを中心に書かれます。
しかし利用者が困るのは失敗時です。

エラーハンドリング仕様を書くと、次が明確になります。

  • どこまでが成功か
  • いつ再操作できるか
  • 誰が復旧するか

結果として、問い合わせが減ります。
そして開発者も迷わなくなります。

成功フローだけの仕様は、完成図です。
エラーまで含めた仕様が、設計図です。

SDDでは、例外処理は最後に付け足すものではありません。
最初に定義することで、システムの振る舞いが初めて安定します。