みなさんこんにちはヒロポンです!
今回はC#でtry{}catch{}を使っていて、VisualStudioに怒られてしまったので、その内容と対応策を書いていきたいと思います。
VisualStudioに怒られた内容
それはコードをある程度書き終わった後の事。
メニュータブからビルド⇒ソリューションでコード分析を実行したところ、以下のようなエラーがたくさん出てきました。
「エラー番号:CA2200 [メソッド名]はキャッチされた例外を再度スローし、その例外を引数として明示的に指定します。最初に例外が発生したスタックの場所を保持するには、’throw’を引数無しで使用してください」
この時に書いていたcatchの内容が以下
try
{
任意の処理
}
catch(Exception ex)
{
throw ex;
}
特に問題なさそうなんですが、怒られてしまいました。
CA2200エラーの公式の見解
公式リファレンスは以下になります。
公式リファレンス
全文英語なので、google翻訳にかけてみるとなんとなく重要な部分はここかなーーとおもいます。
例外をスローした元のメソッドと現在のメソッド間のメソッド呼び出しのリストが失われます。元のスタックトレース情報を例外とともに保持throwするには、例外を指定せずにステートメントを使用します。
エラーの内容とこの文言を見てみると、Exeption exという形でエラーの型を指定してしまうと、だめなのかなーーと思います。
CA2200の対策
取り急ぎthrowのみ書け!といわれたので、下記のように修正しました。
try
{
任意の処理
}
catch
{
throw;
}
こうすれば怒られなくなりました。
原因はスタックトレースの上書き?
今回怒られた内容私も気になったので、原因について調べてみました。
結果、throw exをすると、スタックトレースが上書きされてしまうようなんですね。
スタックトレースについて調べてみたところ下記のような説明が出てきました。
エラーが発生したときに表示される内容で、そのエラーが発生するまでの過程(どんな処理がどの順番で呼び出されたかの流れ)を、ざっくりと表示したもの
スタックトレースについては以下のサイトがわかりやすいですね。
スタックトレース
この内容を見てみると出てくる結論はひとつ。
throw exをすると、スタックトレースが上書きされるので、エラー内容を見るときに、どこでエラーが発生したのか追跡できなくなるよ!だから、throwは引数無しで実行してね!って事だそうです!
完璧に理解はしていないけれども、なんとなくわかった!って感じですね!
コメント