くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

例外の設計について、あらためて考えてみた

例外ハンドリング周りによく悩むので、改めて考え直してみた

ちなみに、例外とエラーは置き換え可能として、区別せず、
try-catch形式を想定してます

全体のイメージ

イメージとしてはこんな感じ

利用者やアプリケーションは、
APIサーバなのか、Web/スマホアプリなのかによって変わるけど、

  • アプリケーション ... 作った部分
  • 利用者 ... アプリケーションを使うユーザやシステム
  • 外部システム ... アプリケーションが利用してる部分
  • 実行環境 ... アプリケーションを動かしてる部分

というイメージ

例外のいろんな分類

例外の分類には色んなバリエーションがあるっぽい

  1. 業務例外とシステム例外
    • 業務例外 ... 業務ロジック(ビジネスロジック)での例外
    • システム例外 ... それ以外のシステムの技術的な例外
  2. 回復可と回復不可
  3. 検査例外と非検査例外(Java)
    • 検査例外 ... コンパイラで処理が強制
    • 非検査例外 ... コンパイラで処理を強制しない
    • 非検査例外は、何もしないと異常終了する(致命的なエラー)

組み合わせ的な感じで、

  • 業務例外 x 回復可
  • 業務例外 x 回復不可
  • システム例外 x 回復可
  • システム例外 x 回復不可
  • システム例外 x 致命的なエラー

のような感じのバリエーションが多い印象

業務例外とシステム例外はどこからくるか

大分類としては、業務例外とシステム例外だけど、 それぞれ色んな場所から発生するイメージ

  • アプリの業務ロジック ... 業務例外
  • アプリのそれ以外 ... システム例外
  • DB
    • 業務例外 ... 一意性制約違反など
    • システム例外 ... DBダウンなど
  • API
    • 業務例外 ... 400エラーなど
    • システム例外 ... 500エラーなど

どちらも発生する部分は、どう振り分けるかは各々で検討が必要

例外を利用者にどう伝えるか

それぞれでざっくりしたパターンとしては、以下のイメージ 例外が起こった時の挙動は基本プレゼンテーション層/上位層でを決める

  • 業務例外 x 回復可
    • 利用者にメッセージを表示し、修正&やり直してもらう
  • 業務例外 x 回復不可
    • 利用者にメッセージを表示する
  • システム例外 x 回復可
    • アプリ側でリトライし、だめなら利用者にメッセージを表示する
  • システム例外 x 回復不可
    • 利用者にメッセージを表示する
  • システム例外 x 致命的なエラー
    • 異常終了する

カスタム例外クラスの階層構造

大枠は3つが識別できれば十分かも

  • AppException ... 最上位の例外クラス
    • AppLogicException ... 業務例外
      • メッセージを表示する
    • AppSytemException ... システム例外
      • 必要ならリトライし、それでもだめならメッセージを表示
    • AppFatalException ... 致命的なエラー
      • 異常終了するなど

あとは各々階層化やサブクラスを増やしていく感じ

外部システムの例外をどう扱うか

  • DBやORMの例外
  • APIのエラーレスポンス

など、SDKやライブラリなどサードパーティの例外を そのまま使ってしまうこともあるがよくない

エセDDDっぽく書くと、こんな感じだと思うけど、

用意したカスタム例外クラスにwarpしてから、 ロジック内で扱う形がよい(インフラ層で吸収する形)

また、デバッグするときに、元の例外やスタックトレースが失われないよう、 カスタム例外クラスに引き継ぐことも大事


以上!ざっくりだけど、だいぶ整理できてきた気がする(*´ω`*)

このあたりの本も参考になった!!

ソフトウェア設計のトレードオフと誤り ―プログラミングの際により良い選択をするには Tomasz Lelek

ソフトウェア設計のトレードオフと誤り ―プログラミングの際により良い選択をするには Tomasz Lelek

プログラマが知るべき97のこと 和田 卓人

プログラマが知るべき97のこと 和田 卓人

Good Code Bad ~持続可能な開発のためのソフトウェアエンジニア的思考

Good Code Bad ~持続可能な開発のためのソフトウェアエンジニア的思考

達人プログラマー 第2版 熟達に向けたあなたの旅 David Thomas

達人プログラマー 第2版 熟達に向けたあなたの旅 David Thomas

おまけ: エラーレスポンス形式の標準仕様

Problem JSON

{
    "type": "https://example.com/probs/cant-view-account-details",
    "title": "Not authorized to view account details",
    "status": 401,
    "detail": "Due to privacy concerns you are not allowed to view account details of others. Only users with the role administrator are allowed to do this.",
    "instance": "/account/123456/details"
}

参考にしたサイト様