C#
定石3: Exceptionフィルタ(when句)でcatch内if分岐を排除
出典: C# 例外処理の正解 — try-catch-finally / using / Exception フィルタ (when句) の使い分け — 定石3: Exceptionフィルタ(when句)でcatch内if分岐を排除
// ✅定石3-a: Exceptionフィルタ(when句)でデッドロックだけリトライ
try
{
ExecuteSql();
}
catch (SqlException ex)when (ex.Number == 1205)
{
// SQL Serverデッドロック(Error 1205)の時だけリトライ
Thread.Sleep(100);
ExecuteSql();
}
catch (SqlException ex)when (ex.Number == -2)
{
//タイムアウトの時だけ別処理
Logger.Warn($"SQL Timeout: {ex.Message}");
throw new TimeoutException("DBアクセスがタイムアウトしました", ex);
}
catch (SqlException ex)
{
//上のwhenにマッチしないSqlExceptionはここで捕まる
Logger.Error($"DBエラー: {ex.Number} {ex.Message}");
throw;
}
// ❌ NG: catch内でif分岐すると、フィルタにマッチしなかった例外を再スローし忘れる事故が起きる
try
{
ExecuteSql();
}
catch (SqlException ex)
{
if (ex.Number == 1205){ /* リトライ */ }
else if (ex.Number == -2){ /* タイムアウト */ }
//それ以外を握りつぶしてる罠
}
▸ 実行ボタンで結果を表示
Source収録記事
この snippet は記事の「定石3: Exceptionフィルタ(when句)でcatch内if分岐を排除」セクションに登場する。コードの前後の文脈・ハマりどころの解説は記事本文で。
同じ記事から
8 件// ✅定石1-a: try-catch —例外を捕まえて処理を続ける try { var dt = LoadFromDb(orderId);
▶ 実行可
定石1: try-catch / try-finally / usingの関係(usingは構文糖衣)
#c0aab089a37f
// ✅定石2:入れ子usingで複数IDisposableを扱う using (var conn = new SqlConnection(connStr)) using (var cmd = new SqlCommand("SELECT id, name FROM users WHERE status = @s", conn)) {未収録
定石2:複数IDisposableは入れ子usingで書く
#740c9638ff8a
// ❌ NG: throw ex;はスタックトレースが「rethrowした行」でリセットされる public void OuterMethod() { try
▶ 実行可
定石4: throw vs throw exのスタックトレース挙動
#08d0e82d4c16
// ❌ NG:例外を捕まえてログも吐かず処理を続ける try { SaveOrder(order);未収録
1. catch (Exception){ }で全握りつぶし
#8c7dfdd9cccc
// ❌ NG: finally内で例外が出ると元の例外が上書きされる SqlConnection conn = null; try {未収録
2. finallyで例外スローして元の例外が消える
#2243ed770fc8
// ❌ NG: Open()で例外が出るとDispose()が呼ばれない SqlConnection conn = new SqlConnection(connStr); conn.Open(); // ←ここで例外が出ると、connがusingの外なのでDispose()されない using (conn)未収録
3. usingとOpen()の順序ミス
#22920b27e7c6
