ルール
ハンドル エラー で キャッチ ブロックでエラーを処理する。
空の キャッチ ブロック 静かに エラーを飲み込む エラーを飲み込む、
デバッグ デバッグ を難しくする。
対応言語 Java、 C, C++, PHP、 JavaScript、
TypeScript、 Go、 Pythonはじめに
空のcatchブロックは、本番コードにおける最も危険なアンチパターンの一つです。例外が捕捉されても処理されない場合、エラーは痕跡を残さずに消滅します。アプリケーションは、実行を停止すべきであった破損した状態、無効なデータ、または失敗した操作のまま実行を継続します。ユーザーは、機能が動作しないサイレントな障害を目にしますが、エラーメッセージは受け取りません。運用チームはデバッグするためのログがありません。何かがおかしいという唯一の兆候は、連鎖的な障害によってシステムが使用不能になった数時間後、あるいは数日後に現れます。
なぜ重要なのか
デバッグとインシデント対応: 空のcatchブロックはエラーログを排除します。エンジニアはスタックトレース、エラーメッセージ、または障害が発生した時期や場所の兆候を持たず、問題の再現をほぼ不可能にします。
サイレントデータ破損: 空のcatchブロック内でデータベース操作やAPI呼び出しが失敗した場合、アプリケーションは成功したかのように動作を続けます。レコードは部分的に更新され、トランザクションは不完全になり、破損が発見される頃には監査証跡は失われています。
セキュリティ脆弱性: 空のcatchブロックは、認証エラーや認可チェックなどのセキュリティ障害を隠蔽します。セキュリティ上重要なパスで例外をトリガーした攻撃者は、エラーがサイレントに処理された場合、保護を完全にバイパスする可能性があります。
カスケード障害: エラーが無視されると、アプリケーションは無効な状態で続行されます。失敗した操作の結果に依存する後続の操作も失敗し、エンジニアを実際の根本原因から誤解させる一連の障害が発生します。
コード例
❌ 非準拠:
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 }
);
}
}
これが重要な理由:すべてのエラーはコンテキストとともにログに記録され、デバッグ情報を提供します。エラーは呼び出し元に伝播し、適切なレベルでの適切なエラー処理を可能にします。監視システムはこれらのエラーについてアラートを発することができ、アプリケーションは無効な状態で続行するのではなく、迅速に失敗します。
まとめ
空のcatchブロックは、本番コードでは決して許容されません。捕捉された例外は最低限ログに記録する必要があり、ほとんどは呼び出し元に伝播させるか、特定の回復アクションをトリガーする必要があります。エラーを本当に無視する必要がある場合は、そのビジネス上の正当な理由をコメントで説明し、文書化してください。デフォルトでは、エラーは常に明示的に処理し、サイレントに破棄すべきではありません。

