try〜catchを実装するには
最近仕事でvbsをゴリゴリ書いていたのだけど、vbsにはtry〜catchなんて言語仕様がない。ランタイムエラーが出るとその場でスクリプトエンジンの実行が停止して落ちる。落ちるのはまぁ仕方ないとして、問題はそのときコマンドラインでcscript.exeのリターンコードを%ERRORLEVEL%でチェックしたらなんとcscript.exeは0を返す。ありえない!!!!!!
というわけで、ランタイムエラーで0以外がきちんと返るようtry〜catchの作り方を考えたのだけど、実は同じことを考えてる人が既にいた。
On Error Resume Nextの正しい使い方: Windows Script Programming
基本的な構造は以下のようになる。
Option Explicit Sub Main() Err.Raise(1) End Sub Sub Try() Call Main() End Sub Sub Catch() On Error Resume Next Call Try() End Sub Call Catch() If Err.Number <> 0 Then WScript.Echo Err.Number & ":" & Err.Description WScript.Quit(Err.Number) Else WScript.Quit(0) End If
いわゆる通常の例外処理がある言語の書き方からすると直感的ではないかもけど、エントリーポイントはCall Catchから始まる。で、On Error Resume Nextを宣言した後にTryを呼ぶ。Tryの中でランタイムエラーが発生すると、On Error Resume NextによりTryを呼び出した次の行に実行が遷移する。つまり、Catchが終了する。で、その後ろにErrをチェックするロジックを置いておくとすべてのランタイムエラーが拾えることになる。ここで、エラーを表示して、Quitで正しくリターン値を返せばcscript.exeがきちんと0以外を返せるようになり、みんな幸せになれる。