参考書には下記の例が挙げられているのですが、
どこの誰が書いたかもわからないネットの記事ならともかく、一般に販売されている書籍にそのようなこと書いてあることはないはずなので、このスレッドは釣りを疑うレベルですが・・・
質問に書いてあるコードは、はっきり言ってデタラメでそれをベースに議論できるレベルには無いので、自分が持っている Microsoft の本に質問のコードとよく似たものがあったのでそれをベースに説明します。
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;
}
上記は、データベースに INSERT する際に PK 制約違反で発生する例外のみ catch して 2 重登録エラーとしてユーザーに再入力を促し、その他は再 throw してランタイムに拾わせてアプリケーションを停止させるというものです。
①内側のtry
余計なものを catch しないよう、PK 制約違反が発生するコード一行のみを囲む。
②下記の例ではtry内に更にtry-catchを記載していますが
外側の try はどこで例外が発生しても必ず connection.Close(); に制御が飛んで接続リークを防止するため。内側の try は上に説明した通り。
③e1.Messageは読み取り専用とのエラーが出てしまいます。
質問のコードの内側の catch 内のコードはメチャクチャで議論の対象になるようなものではありません。Exception を catch することがあるとすると、例えば、原因不明の問題が発生していてその調査のためログを取るためぐらいでしょうか。ログを取ったら即 throw し、それをランタイムに拾わせてアプリケーションを停止させます。
参考に、.NET アプリの例外処置について Microsoft Bolg に書いてあったことを要約して紹介しておきます(Bolg は今はリンク切れです)。
(1) 予測可能で正しい業務フローに戻すことができる「業務エラー」(例:ユーザーの入力間違い)と、予測できないもしくは予測はできても何の対応もできない「例外」(例:DB サーバーダウン)を区別して対処。
(2) 「例外」はランタイムに拾わせてアプリケーションを停止させる。無かったことにして、ユーザが作業を続けられるようにすると、強制的に停止させるより好ましからざる状況に陥るかも(ユーザーが大事なデータを壊したりとか)。
(3) よほどのことがない限り try-catch は書かない。
(4) キャッチせざるを得ない場合でも Execption はキャッチしない。キャッチせざるを得ないとしても範囲を絞る。例えば DB 関係の例外が予測されるなら SqlException に限定して catch し、Number プロパティなどでエラーの内容を調べて対処するとか。
(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
以下の記事も参考になると思います。
例外の推奨事項
https://docs.microsoft.com/ja-jp/dotnet/standard/exceptions/best-practices-for-exceptions