
2026/03/02 8:29
二つの種類の誤り
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary
この記事は、開発者が「期待されるエラー」と「予期しないエラー」を意図的に区別し、それぞれを異なる方法で扱うことでソフトウェアの信頼性を向上させるべきだと主張しています。
- 期待されるエラー – ユーザー入力や環境条件(バリデーション失敗、ネットワーク障害、権限拒否など)によって発生し、回復可能です。これらは低い重大度(WARN/INFO)でログに残し、フォールバックロジックを用いて優雅に処理すべきです。
- 予期しないエラー – アサーション違反、論理ミス、ヌルポインタ例外、データ整合性問題などのバグは、クラッシュやパニックを引き起こし、より高い重大度(ERROR/FATAL)でログに残すべきです。
著者は、Node.js のメモリ割り当て事故を例に挙げ、動的言語でも予測可能な失敗が発生することを示しています。Rust と Zig は既に「エラーは期待される」というマインドセットを採用しているのに対し、JavaScript と Python では多くの障害をサプライズとして扱う傾向があります。この分類はプロジェクトの性質(クイックプロトタイプからミッションクリティカルなシステムまで)によって決まり、厳格なエラー処理と柔軟なスクリプティングとの間に広範な緊張を反映しています。
著者はチームに対し、失敗をより多く期待する傾向へ移行するよう促しており、日常運用で多くの予期せぬ問題が浮上することを想定しています。この前向きな姿勢は早期バグ検出、クラッシュ減少、業界慣行の強化につながり、最終的にはユーザー、企業、およびソフトウェアエコシステム全体に利益をもたらすと結論付けています。
本文
要点だけで言うと:
エラーは大きく2つに分類できると考えています。
- 期待されるエラー(Expected errors) – 通常の運用中に発生し得るもの(例:ユーザー入力の検証失敗)。開発者側の過ちではなく、優雅に処理すべきです。
- 予期しないエラー(Unexpected errors) – バグや仮定違反(例:ヌルポインタ例外)のこと。通常はクラッシュを起こし、コード上で何かがうまくいかなかったことを示します。
期待されるエラー
| 例 | なぜ期待されるのか | 一般的な対処 |
|---|---|---|
| ユーザーが無効なデータを入力した際の検証エラー | 入力は開発者の制御外 | や でログ、メッセージ表示、フォールバック使用 |
| ネットワーク障害(例:インターネット不可) | 外部要因 | 再試行、ユーザーへの通知、 ログ |
| 権限エラー(許可されていないファイルを読む際など) | システムが禁止している | ユーザーへ通知、 ログ |
- 復旧 – 期待されるエラーは復旧可能です。例外投げるよりも、
や nullable 型、あるいはエラーコードで結果を返すほうが望ましい。Result - ログ –
またはWARN
を使用する。警告が頻発しているなら原因究明を。INFO
予期しないエラー
| 例 | なぜ予期しないのか | 一般的な対処 |
|---|---|---|
| アサーション失敗(例:空文字列が許されていない場所で空文字) | 契約違反 | クラッシュ / パニック |
| 論理エラー(未初期化の依存関係など) | 仮定が誤っている | クラッシュ / パニック |
| ヌルポインタ例外 | 予想外のヌル | クラッシュ / パニック |
| 信頼できるソースからの不正データ(例:DB破損) | バグや破損 | クラッシュ / パニック |
- 復旧 – 原則として試みません。プログラムをクラッシュさせ、バグを顕在化させます。
- ログ –
やERROR
を使用します。これらは真剣な問題を示す。FATAL
線の所在
- プロトタイピング / クイックスクリプト – ほとんどのエラーを予期しないものとして扱い、ネットワーク・ファイルシステム・ユーザー入力の問題は処理せずに済ませます。
- ミッションクリティカルなシステム(例:宇宙探査機) – ほぼすべてを期待されるものとして扱い、ハードウェア障害でさえも優雅に対処します。
実際には多くのアプリケーションはその中間に位置し、エラーが「期待できる」か「予期しない」かはタスクと失敗許容度によって決まります。
言語ごとの慣習
| 言語 | 一般的なエラークラス分け |
|---|---|
| Rust / Zig | 多くのエラーが期待される(必ず処理しなければならない) |
| JavaScript / Python | エラーはしばしば予期しないものとして扱われる(例外がそのまま伝搬) |
私は、本番コードには厳格なコンパイラを、スクリプトやプロトタイプには緩い言語を好みます。これはそれぞれのエラーフィロソフィーに合致しています。
結論として:
予測可能なものは 期待される として扱い、適切に処理します。サプライズは 予期しない と見なし、そのまま顕在化させます。このマインドセットが信頼性を高め、エラー処理戦略を明確にします。