ルール
ハンドル エラー で キャッチ ブロックでエラーを処理する。
空の キャッチ ブロック 静かに エラーを飲み込む エラーを飲み込む、
デバッグ デバッグ を難しくする。
対応言語 Java、 C, C++, PHP、 JavaScript、
TypeScript、 Go、 Pythonはじめに
空のキャッチ・ブロックは、プロダクション・コードにおける最も危険なアンチパターンの1つである。例外がキャッチされたにもかかわらず処理されない場合、エラーはトレースされずに消えてしまう。アプリケーションは、破損した状態、無効なデータ、あるいは実行を止めるべき操作に失敗したまま実行を続けます。ユーザーは、エラーメッセージは受け取らないものの、機能が動作しないサイレントエラーを目にすることになる。運用チームにはデバッグするためのログがない。何かが間違っていることを示す唯一の兆候は、数時間から数日後、連鎖的な障害によってシステムが使用不能になったときにやってくる。
なぜそれが重要なのか
デバッグとインシデント対応:空のキャッチブロックはエラーログを排除する。エンジニアは、スタックトレース、エラーメッセージ、いつ、どこで障害が発生したかを知ることができず、問題の再現がほとんど不可能になります。
サイレント・データ破損:空のキャッチブロック内でデータベース操作やAPIコールが失敗すると、アプリケーションは成功したかのように処理を続行する。レコードは部分的に更新され、トランザクションは不完全で、破損が発見される頃には監査証跡は消えている。
セキュリティの脆弱性:空のキャッチ・ブロックは、認証エラーや認可チェックのようなセキュリティの失敗を覆い隠してしまう。攻撃者が、セキュリティ上重要なパスで例外をトリガーする場合、そのエラーが黙って飲み込まれると、防御を完全にバイパスしてしまうかもしれません。
障害が連鎖する:エラーを飲み込むと、アプリケーションは無効な状態で継続する。失敗した操作の結果に依存する後続の操作も失敗し、エンジニアを実際の根本原因から惑わせる失敗の連鎖が発生する。
コード例
非準拠:
async function updateUserProfile(userId, profileData) {
try {
await db.users.update(userId, profileData);
await cache.invalidate(`user:${userId}`);
await searchIndex.update(userId, profileData);
} catch (error) {
// TODO: handle error
}
return { success: true };
}なぜ間違っているのか:何らかの操作が失敗しても、エラーは黙って無視され、関数は成功を返す。データベースは更新されるかもしれませんが、キャッシュの無効化に失敗し、古いデータが残るかもしれません。あるいは、検索インデックスの更新に失敗し、ログやアラートで問題を示すことなく、ユーザーを検索不能にします。
✅ 準拠:
async function updateUserProfile(userId, profileData) {
try {
await db.users.update(userId, profileData);
await cache.invalidate(`user:${userId}`);
await searchIndex.update(userId, profileData);
return { success: true };
} catch (error) {
logger.error('Failed to update user profile', {
userId,
error: error.message,
stack: error.stack
});
throw new ProfileUpdateError(
'Unable to update profile',
{ cause: error }
);
}
}
なぜこれが重要なのか:すべてのエラーはコンテキストとともにログに記録され、デバッグ情報を提供する。エラーは呼び出し元に伝わり、適切なレベルで適切なエラー処理を行うことができます。監視システムはこれらのエラーについて警告を発することができ、アプリケーションは無効な状態で継続するのではなく、迅速に失敗する。
結論
空のキャッチ・ブロックは、運用コードでは決して許されない。キャッチされた例外は、最低限ロギングする必要があり、ほとんどの場合、呼び出し元に伝搬するか、特定の回復アクションをトリガーする必要があります。エラーを本当に無視する必要がある場合は、ビジネス上の正当性を説明するコメントを添えて、その理由を文書化してください。デフォルトは、常に明示的にエラーを処理することであり、黙ってエラーを破棄することではありません。
.avif)
