error-handling-robustness
Skill0 starsChanged 4 months agoMITView on GitHub
Robust error-handling patterns: errors as values, fail fast with assertions, no silent failures, actionable error messages. Use when writing or reviewing code with try/catch, error returns, input boundaries, or fallback logic, or when the user says エラー処理, 例外, 握りつぶし. Not for diagnosing an existing failure (use systematic-debugging) or log/monitoring design (use logging-observability).
In this repository14 other files it gives its agents.
- ai-code-verificationSkill
- ci-cd-hardeningSkill
- legacy-code-navigationSkill
- logging-observabilitySkill
- naming-readabilitySkill
- performance-optimizationSkill
- plan-then-codeSkill
- project-conventionsSkill
- refactoring-disciplineSkill
- safe-release-practicesSkill
- scalability-designSkill
- secure-input-handlingSkill
- test-suite-designSkill
- web-api-designSkill
The file
Files
Error Handling Robustness
エラーは隠すものではなく、明示的に扱う値である。握りつぶし(silent failure)を作らない。想定内の失敗と想定外の異常を区別する。
鉄則
- すべての
catch/exceptは、最低限「ログに残す」か「呼び出し元に伝播する」のどちらかを必ず行う。 何もしない・握りつぶすcatchブロックは作らない。 - 想定内の失敗(ユーザー入力エラー、ネットワーク障害、リソース未検出等)は型付きエラー・戻り値として呼び出し側に処理させる。想定外の異常(プログラムのバグに起因するもの、到達不能なはずの分岐)はfail-fast(即座に停止・assert・例外)で処理する。
- エラーメッセージには「何が」「なぜ」失敗したかに加え、可能な限り「対処のヒント」(どの入力が問題だったか、次に何をすべきか)を含める。
- コード中の「ここでは必ずこの条件が成り立つ」という暗黙の前提は、assert・契約チェックとして明文化する。冗長に見えても書く。
作業手順
ステップ1: 「この処理は失敗しうるか」を最初に確認する
関数・エンドポイントを実装する前に、失敗しうる操作(I/O、外部呼び出し、パース、型変換、配列アクセス等)を洗い出す。失敗しうるなら、戻り値・型・例外のいずれかで明示的に表現する設計にする。
ステップ2: 想定内 vs 想定外を分類する
- 想定内(呼び出し側が対処できる): ユーザー入力の不正、ネットワークタイムアウト、リソース未検出、認可エラー → 型付きエラー・Result風の戻り値・チェック例外として返す。呼び出し側にハンドリングを強制する設計が望ましい。
- 想定外(プログラムのバグ、到達しないはずの状態): nullが来るはずのない箇所にnullが来た、switchのdefaultに来た、不変条件が破れた → assertまたは即座に例外を投げてfail-fastする。回復しようとしない。
ステップ3: catch/exceptを書くときの必須チェック
- 何かをキャッチしたら、必ず次のいずれかを行う。
- ログに構造化して残す(スタックトレース・入力値・コンテキストを含める)
- 呼び出し元に再送出する、または型付きエラーとして返す
- 明示的なフォールバック処理を行う(その場合はフォールバックした事実を必ずログに残す)
- 上記のいずれも行わない
catch { }/except: passは禁止。書きそうになったら「これは本当に無視してよいエラーか」を自問し、無視してよい場合でも理由をコメントで残す。 - エラーを再送出する際、元のエラー情報(原因・スタックトレース)を握りつぶさない(
raise from等でチェーンを保持する)。
ステップ4: エラーメッセージを実行可能にする
悪い例: "Error occurred" / "Invalid input"
良い例: "Failed to parse config.yaml: line 12, expected string but got null (key: 'timeout')"
チェック項目:
- 何が失敗したか(対象・操作)が書かれているか
- なぜ失敗したか(原因)が書かれているか
- 可能なら次に何をすべきかのヒントが書かれているか
- 機密情報(パスワード、トークン、個人情報)を含んでいないか
ステップ5: assertで仮定を文書化する
- 関数の入口で「この引数はnullではない」「このリストは空ではない」等の前提をassert/契約チェックとして書く。
- 「起こらないはず」の分岐(elseの最後、switch/matchのdefault)には、到達したら即座に失敗するassertか例外を入れる。
- リファクタリングでassertを削除する前に「本当に不要になった前提か」を確認する。多くの場合、暗黙の前提を消してしまうだけのリスクがある。
チェックリスト
- すべてのcatch/exceptがログ記録または伝播のいずれかを行っているか
- 想定内の失敗と想定外の異常を区別して処理を分けているか
- エラーメッセージに「何が・なぜ・どうすれば」が含まれているか
- 暗黙の前提条件をassertとして明文化したか
- エラー情報(原因・スタックトレース)をチェーンとして保持しているか
- リトライ・フォールバックを入れた場合、それをログに残しているか
- エラーメッセージに機密情報が漏れていないか
アンチパターン集
| やりがちな実装 | 現実・対処 |
catch (e) {} で何もしない | 障害調査時に何が起きたか永久に分からなくなる。最低限ログを残す |
catch (e) { console.log(e) } だけで終える | ログだけでは呼び出し元が失敗を検知できない。伝播も必要か検討する |
汎用例外Exception/Errorを握りつぶしてデフォルト値を返す | 「失敗したのに成功したように見える」状態を作る。呼び出し元に失敗を伝える設計にする |
| 全てのエラーを同じ扱いで再試行する | 想定外のバグ由来のエラーまでリトライすると無限ループや隠れた障害の温存につながる。想定内/想定外を区別する |
エラーメッセージに"error"とだけ書く | デバッグ不能。対象・原因・対処ヒントを含める |
| 「ここはnullにならないはず」と思ってチェックを省く | 暗黙の前提はassertとして明文化しないと将来壊れても気づけない |
| リファクタリング時にassertを一律削除する | assertは仕様書でもある。不要になった根拠を確認してから消す |
出典
- Rust公式ドキュメント — Error Handling(
Result<T, E>によるエラーの明示的伝播) - Go言語の
(value, error)戻り値パターンとRustの比較 — Comparing Error Handling in Rust and Go - John Carmack — assertを仮定の検証・ドキュメントとして多用する考え方(cbarrete.com/carmack.html)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

