C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

■96702 / 1階層)  try...catch の文字列の設定方法について
□投稿者/ WebSurfer (2178回)-(2021/01/11(Mon) 14:50:35)
No96698 (天海 さん) に返信

catch(Exception ex) が問題ないと思っているかもしれないので一言。

それだと再 throw しない限りすべての例外を握りつぶしてなかったことにしてしまいますが、それは
いろいろまずいので止めるべきです。

.NET アプリの例外処置について、自分的に一般的と思うことを書きます。

(1) 予測可能で正しい業務フローに戻すことができる「業務エラー」(例:ユーザーの入力間違い)と、
  予測できないもしくは予測はできても何の対応もできない「例外」(例:DB サーバーダウン)を
  区別して対処。

(2) 「例外」はランタイムに拾わせてアプリケーションを停止させる。無かったことにして、ユーザが
  作業を続けられるようにすると、大事なデータを壊したり、強制的に停止させるより好ましからざ
  る状況に陥るかも。

(3) よほどのことがない限り try-catch は書かない。

(4) キャッチせざるを得ない場合でも Execption はキャッチしない。キャッチせざるを得ないとしても
  範囲を絞る。例えば DB 関係の例外が予測される SqlException に限定して catch するとか。

(5) 間違って補足してしまった例外は throw する。(注:catch ブロックでキャッチした例外を throw 
  するとスタックトレースが途切れるので単に throw と書く)

(6) ユーザーへの通知が必要なら、集約的例外処置を利用する。

それから、.NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも 
Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見てください。

破損状態例外を処理する
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2009/february/clr-inside-out-handling-corrupted-state-exceptions

自分が持っている Microsoft の本に、上に書いた原則に則ったサンプルが載っていたので紹介しておきます。

データベースに INSERT する際に PK 制約違反で発生する例外のみ catch して業務エラー(2 重登録)
としてユーザーに再入力を促し、その他は再 throw してランタイムに拾わせてアプリケーションを停止
させるというものです。


public bool InsertAuthors()
{
    var connection = new SqlConnection("接続文字列");
    var command = new SqlCommand("INSERT INTO authors VALUES ('172-32-1176', 'White', ...)", connection);
    try
    {
        connection.Open();
        try
        {
            command.ExecuteNonQuery();
        }
        catch(SqlException sqle)
        {
            if (sqle.Number == 2627)
            {
                return false;
            }
            else
            {
                throw;
            }
        }
    }
    finally
    {
        connection.Close();
    }

    return true;
}

以下の記事も参考になると思います。

例外の推奨事項
https://docs.microsoft.com/ja-jp/dotnet/standard/exceptions/best-practices-for-exceptions

編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←try...catch の文字列の設定方法について /天海 返信無し
 
上記関連ツリー

try...catch の文字列の設定方法について / 天海 (21/01/11(Mon) 11:30) #96698
Re[1]: try...catch の文字列の設定方法について / Azulean (21/01/11(Mon) 13:34) #96700
│└ Re[2]: try...catch の文字列の設定方法について / とっちゃん (21/01/11(Mon) 14:11) #96701
Re[1]: try...catch の文字列の設定方法について / WebSurfer (21/01/11(Mon) 13:33) #96699
│└ Re[2]: try...catch の文字列の設定方法について / 天海 (21/01/11(Mon) 14:52) #96703
│  ├ Re[3]: try...catch の文字列の設定方法について / WebSurfer (21/01/11(Mon) 18:12) #96704
│  │└ Re[4]: try...catch の文字列の設定方法について / 天海 (21/01/12(Tue) 08:29) #96705
│  │  └ Re[5]: try...catch の文字列の設定方法について / WebSurfer (21/01/12(Tue) 09:25) #96706
│  └ Re[3]: try...catch の文字列の設定方法について / 魔界の仮面弁士 (21/01/12(Tue) 10:47) #96707
│    └ Re[4]: try...catch の文字列の設定方法について / 天海 (21/01/12(Tue) 11:20) #96708 解決済み
try...catch の文字列の設定方法について / WebSurfer (21/01/11(Mon) 14:50) #96702 ←Now

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信