小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


VBScriptではエラーをRaiseすると関数の戻り値が返らない

VBScriptでは、関数内でエラーをRaiseするとFunction(関数)の戻り値が返ってきません。以下のコードで実験してみます。
Hoge関数では、戻り値をセットした後に、意図的にエラーを呼び出し元へRaiseしています。

On Error Resume Next

' 関数Hogeの呼び出し
dim a : a = Hoge()
If Err.Number <> 0 Then
  WScript.Echo Err.Number & "::" & Err.Source & "::" & Err.Description
End If
WScript.Echo a

' Hogeという文字列を返す関数
Function Hoge()
  On Error Resume Next
  
  Hoge = "hoge"
  On Error GoTo 0
  Err.Raise vbError + 1, "エラー発生場所", "エラー詳細"
  
End Function

上記コードの実行結果は、以下のようになります。

11::エラー発生場所::エラー詳細

この場合、呼び出し元でHoge関数の戻り値を変数aに格納していますが、WScript.Echo aの結果は、何も出力されません。エラーをRaiseしつつ、関数の戻り値を呼び出し元へ返したい場合には、以下の方法を用います。

  1. 参照渡しで渡された関数の引数を利用し、戻り値を返す
  2. エラーが発生した際に、Error.Raiseするのではなく、エラー情報を保持したまま、Exit Functionする
参照渡しを利用する方法
On Error Resume Next
dim a, b
b = Hoge(a)
If Err.Number <> 0 Then
  WScript.Echo Err.Number & "::" & Err.Source & "::" & Err.Description
End If
WScript.Echo a

Function Hoge(byref a)
  On Error Resume Next
  
  Hoge = "hoge"
  a = "hoge"
  On Error GoTo 0
  Err.Raise vbError + 1, "エラー発生場所", "エラー詳細"
  
End Function
Exit Functionを用いる方法
On Error Resume Next
dim a : a = Hoge()
If Err.Number <> 0 Then
  WScript.Echo Err.Number & "::" & Err.Source & "::" & Err.Description
End If
WScript.Echo a

Function Hoge()
  On Error Resume Next
  
  Hoge = "hoge"
  Err.Raise vbError + 1, "エラー発生場所", "エラー詳細"
  Exit Function ' ←この先処理がないので、意味はありませんが、
                ' 処理が存在した場合を仮定しています。
  
End Function

上記のようなコードを書く際には、一度設計を見直す必要があると思います。エラーオブジェクトにエラー情報を保持したまま、戻り値を返すということは多少なりとも、トリッキーなコードになるため、もう少しシンプルにできないかと見直すことが大事だと思います。今日、自分でこんな感じのコードを書いてて、思った。