VB.NETでTry-Catch-Finallyってどう書くの?

そもそも Try-Catch-Finally って何者?

「例外処理」と聞くと、ちょっと身構える方も多いかもしれません。
でも実際は「やばそうな処理を安全なクッションでくるむ」――ただそれだけです。

  • Try:まずやってみるブロックです。ここでワクワクしながら処理を試します。
  • Catch:もし転んだら(=例外が起きたら)ここで受け止めます。
  • Finally:転んでも転ばなくても、最後に後片づけをします。床を雑巾がけするイメージです。

難しい概念に見えますが、ざっくり言うと「チャレンジ → エラー対応 → お片づけ」の三段構えです。


よくある「一般的な説明」にモヤッとする理由

解説サイトを巡ると、

Try で処理を書き〜 Catch でエラーハンドリングし〜 Finally で必ず実行される処理を書きます。
と一本調子で説明されることが多いです。

でも実際にコードを書くとき、「どこに何を書く?」 があいまいだと手が止まります。

  • Catch は何個でも良いの?
  • Finally って毎回書くべき?
  • 「とりあえず Exception で全部捕まえればいいや」はアリ?

そんな曖昧さが、初心者だけでなく中堅開発者の足も意外と引っ張ります。


動作確認環境

下記の環境で動作確認しています。

  • .NET9
  • Visual Studio 2022

雑なサンプルですが、ソースコードはこちら


もう少し寄り添ってみる:ポイント別の整理

1. Catch は具体的な型から書く

例外にはたとえば DivideByZeroExceptionIOException など、専門職のように多くの種類があります。
まずは「起こりそうな特定の例外」から Catch しましょう。
最後に力技(Exception)を置けば、万が一の拾い漏れを防げます。

Try
  Dim a = 10
  Dim b = 0
  Dim answer = a \ b ' ゼロ除算の例
Catch ex As DivideByZeroException
    Console.WriteLine("ゼロで割っちゃいました: " & ex.Message)
Catch ex As Exception
    Console.WriteLine("想定外の例外です: " & ex.Message)
End Try

2. Finally は「絶対やるべき後始末」があるときだけ

毎回書けと言われがちですが、必ずしも必須ではありません
たとえばファイルを開いたら閉じる、DB 接続を開いたら閉じる。
そういった「リソース解放」が必要なときにだけ使うとスッキリします。

3. Try の外で初期化する勇気

以下のように、リソース変数は Try の外で宣言しておくと Finally で扱いやすいです。

Dim sr As StreamReader = Nothing
Try
    sr = New StreamReader("sample.txt")
    Console.WriteLine(sr.ReadToEnd())
Catch ex As IOException
    Console.WriteLine("ファイル操作でエラー: " & ex.Message)
Finally
    If sr IsNot Nothing Then sr.Dispose()
End Try

「Nothing チェックが面倒だな」と感じる方は Using ステートメントも検討してください。
これも立派なクッション材です。


例外処理を巡る “あるある” な葛藤

  • 「全部 Exception で拾えばラクなのでは?」問題
    → たしかにコンパイルは通ります。でもエラー原因の切り分けが難しくなり、運用時に首を絞めがちです。
  • 「Finally でログ書けばいいや!」問題
    → Finally は必ず通るので便利ですが、正常処理も異常処理も区別せずログが出ます。
    結果、ログが洪水のようになって後でつらい思いをします。
  • 「Try のネスト地獄」問題
    → ひたすら Try…Catch…Finally… が深くなると読めたものではありません。
    メソッドを細かく分けてネストを浅く保つ、といったリファクタリングが必要です。

とはいえ「堅苦しすぎる」のも考えもの

正直、学習段階で「究極の美しい例外処理」を追い求めると、コードが書けなくなります。

  • まずは動くものを作り、
  • ログで状況を確認し、
  • 徐々に細かい Catch を増やす

この三ステップで肩の力を抜きつつ改善していけば十分です。


具体例で流れをつかむ

「座学は分かったけど、実務っぽいサンプルが欲しい!」

という声が聞こえた気がするので、コンソールアプリを例に一連の流れを載せます。

Module Program
    Sub Main()
        Console.WriteLine("割り算サービスを開始します")
        Console.Write("割られる数を入力してください: ")
        Dim dividend = Integer.Parse(Console.ReadLine())

        Console.Write("割る数を入力してください: ")
        Dim divisor = Integer.Parse(Console.ReadLine())

        Try
            Dim result = SafeDivide(dividend, divisor)
            Console.WriteLine($"結果は {result} です")
        Catch ex As DivideByZeroException
            Console.WriteLine("おっと! 0 では割れません。")
        Catch ex As FormatException
            Console.WriteLine("数字をちゃんと入れてください。")
        Catch ex As Exception
            Console.WriteLine("想定外のエラーが起きました: " & ex.Message)
        Finally
            Console.WriteLine("割り算サービスを終了します")
        End Try
    End Sub

    Private Function SafeDivide(a As Integer, b As Integer) As Double
        Return a \ b
    End Function
End Module
  • FormatException:数値入力ミス用
  • DivideByZeroException:ゼロ除算用
  • Exception:保険的まとめ取り

これだけで、入力ミスやゼロ除算でもアプリが落ちず、ユーザーに優しい挙動になります。


Try-Catch-Finally をもっと使いこなす Tips

  1. 複数の Catch を書く順番
    具体的な派生型 → 汎用的な親クラス の順に並べます。
    逆にすると前の段階で全部拾われ、下の Catch が死文化します。
  2. 再スロー(Throw)の活用
    エラーログを残した後に Throw だけ書くと、元の例外を上位に投げ直せます。
    ログ取りつつ、呼び出し元に判断を委ねられるので便利です。
  3. Using との併用
    Using でリソース解放を自動化しつつ、Try-Catch を外側に書くと読みやすさが向上します。
Try
    Using conn As New SqlConnection(connStr)
        conn.Open()
        ' DB 処理……
    End Using
Catch ex As SqlException
    ' ここでだけ DB 例外を扱う
End Try

よくある FAQ

疑問考え方
Finally を書かずに Using だけで良い?片付け対象がリソースだけならそれで十分です。
Catch で Exception だけ書くのはダメ?プロトタイプなら OK ですが、本番では原因究明が困難になります。
関数の中で Try を複数書くべき?1 関数 1 主旨が原則です。気づけばネストが深いなら分割を検討しましょう。

というわけで、まとめです

  • Try-Catch-Finally は「チャレンジ → エラー対応 → お片づけ」の三段構え
  • Catch は 具体例外 → 汎用例外 の順で並べると見通しが良いです。
  • Finally は「絶対やる後始末」があるときだけ。不要なら潔く省いて OK です。
  • 初めは Exception だけで捕まえても大丈夫。動かしながら改善しましょう。

例外処理は奥が深いですが、最初から完璧を目指すより「安全に壊れにくくする」意識で少しずつ整えていく方が、心もコードも楽になります。

読んでくださったあなたの Try-Catch-Finally ライフがちょっとでも快適になれば嬉しいです。
それでは、良い VB.NET コーディングを!