この記事のポイント

  • 例外有無でAPI設計をどう分離整理するかをレビューアーが読み解く技術を体系整理
  • 契約整理・利用者責務・API境界設計をレビュー支援可能にする
  • 現場レビューで「API粒度の設計崩壊」を防止する技術力を習得

そもそも例外有無によるAPI設計分離とは何か

C++では同じ処理内容でも、API契約設計として「例外有無でAPIを分ける」べき場面が多い

例外利用API 例外非利用API
正常完了を原則前提 エラーが通常パス
例外 → 異常状態通知 戻り値でエラー返却
呼出側が例外安全責務を持つ 呼出側が全分岐処理責務を持つ

レビューアーは「このAPIは例外型契約で出すべきか?コード型で出すべきか?」を常に設計意図から読み解く必要がある。

なぜこれをレビューするのか

  • API契約粒度が統一されず崩壊するケースが頻発
  • 利用者責務が不明確化 → 保守事故の温床に
  • 契約設計が属人文化に依存化しやすい
  • レビュー段階でAPI契約を可視化整理できるレビュー文化が重要

レビューアー視点

  • このAPIの主利用層は誰か?
  • 呼び出し側が例外ハンドリング文化に合致する層か?
  • 契約破綻 vs 予測可能系が契約で明文化されているか?
  • 例外設計文化 or エラーコード設計文化どちらで統一するか?
  • API境界毎に責務移譲整理が完了しているか?

開発者視点

  • 公開API契約では例外有無を設計段階で固定宣言
  • C++文化に沿う層は例外統一優先
  • 組込・制御・移植対象層ではコード型統一
  • 内部層封じ込めは例外→コード吸収層を設計

良い実装例

例1:例外統一API

例外統一API設計
void registerUser(const User& user) {
    if (user.id <= 0) {
        throw std::invalid_argument("Invalid user id");
    }
    if (!db.save(user)) {
        throw DatabaseUnavailable("DB failure");
    }
}
  • 契約破綻 → invalid_argument
  • 外部障害 → custom exception

例2:エラーコード統一API

エラーコード統一API設計
enum class SaveResult {
    Success,
    ValidationError,
    DBFailure
};

SaveResult registerUser(const User& user) {
    if (user.id <= 0) return SaveResult::ValidationError;
    if (!db.save(user)) return SaveResult::DBFailure;
    return SaveResult::Success;
}
  • 全責務を戻り値に統一

レビュー観点

  • API公開契約型に例外有無方針が統一宣言されているか
  • 呼出層文化に適合する方式で設計されているか
  • 設計ドキュメントに契約方針が固定宣言されているか
  • 内部層は統一吸収層が存在するか
  • 監視通知経路が例外有無に依存しない構成になっているか

良くない実装例: ケース1(API群で混在)

API間で統一崩壊
class UserService {
public:
    void saveUser(const User& user);  // 例外方式
    SaveResult updateUser(const User& user);  // エラーコード
@Reviewer
同一責務API群内で例外/コード方式が混在しています。統一設計してください。

改善例

改善例(例外方式統一)
SaveResultを廃止し例外方式へ統一

良くない実装例: ケース2(公開API崩壊)

公開API不統一
void apiEntry(User u) {
    try {
        service.save(u);
    } catch (...) {
        return SaveResult::DBFailure;
@Reviewer
外部API契約型が例外有無で不統一です。公開契約は責務層に応じ統一してください。
} }

改善例

改善例(契約統一)
公開層ではSaveResult型APIで統一

良くない実装例: ケース3(内部層崩壊)

内部吸収層不在
repository.save();  // 例外方式
dao.save();         // コード方式
@Reviewer
内部層で例外吸収統一層が未設計です。統一Adapter層を設計追加してください。

改善例

改善例(吸収層整理)
repository層内部で例外→コード吸収層配置

PlantUML:例外有無API責務整理図

UML Diagram

API契約統一テンプレート

層分類 推奨方針 理由
外部公開API コード方式 言語中立・安定契約
内部サービスAPI 例外方式 設計自然文化維持
デバイス層 コード方式 組込文化適合
共通ライブラリ層 例外方式 C++標準適合

レビューアーはこの表の選択根拠を毎回説明可能に整理する。

通知統一設計例

障害通知経路統一
try {
    service.process();
} catch (const DatabaseUnavailable& e) {
    monitoring.notify("DB_FAILURE");
} catch (...) {
    monitoring.notify("FATAL");
}
  • 例外有無に関係なく通知整理可能

典型レビュー質問集

質問例 意図
このAPIの利用者は例外文化に適合していますか? 呼出層文化整合性確認
API公開契約ドキュメントは統一されていますか? 契約可視化確認
内部吸収層は整理されていますか? 移植安全性確認
モニタリング通知は統一経路化されていますか? 運用性確認

レビューアーは契約文化統一支援レビュー文化を現場で確立する。

観点チェックリスト

まとめ

レビューアーがAPI契約分離レビューで常に問うべきは
「このAPI契約は誰がどう利用し、文化として統一されているか?」
です。

  • API文化 → 設計層別文化宣言
  • 統一契約 → 契約型ドキュメント宣言
  • 吸収層文化 → 内部封じ込め層整理
  • 運用文化 → 通知経路統一

レビュー現場では
「API契約文化をレビュー文化で早期確定させる」
ことで長期品質と設計安定性が保証されます。