< mt-comments.cgi に簡易スパムフィルタを実装する | WSH でショートカットを作成する >

January 20, 2005

VB6 実行時エラーのコールスタックを採取する小ネタ

VB6 で、エラーをハンドリングする際のスケルトン。例によって VB6 に限定しているのは、.NET はまだ仕事で使ってないので語るものを持たないためです。

エラーを必ずハンドリングする必要があるのは、呼出元を持たないプロシージャ、つまり、Sub Main() 、イベントプロシージャ、またはコールバックプロシージャ(ウインドウをサブクラス化した時のウインドウプロシージャとか、フックプロシージャのこと)などで、自分自身が大元の呼び出し元であるプロシージャ達です。それ以外のエラーは呼出元に返すことができます。

呼出元に返す際に、 Err オブジェクトにプロシージャ名をセットしていくと、前述の呼出元プロシージャでは、呼出順をとることができます。

'イベントプロシージャ
Option Explicit
Private Const MODULE_NAME	As String = "Form1"

'------------------------------------------------------------------
'プロシージャ名:  :Form_Initialize
'説明:            :
'------------------------------------------------------------------
Private Sub Form_Initialize()
'============= Declare ==============
'============= Initiarize ===========
On Error GoTo ErrorHandler
    
'============= Main =================

    ' 処理...
    
'============= Release ==============
ExitHandler:
    Exit Sub
'============= Error ================
ErrorHandler:
    Call HandleError(Err.Number, Err.Source, Err.Description, MODULE_NAME & ".Form_Initialize")

    Resume ExitHandler
End Sub

HandleError って関数の中で、ログをはくなりしましょうってイメージ。

で、その他のプロシージャ。要するに間接的に呼び出されるやつ。ここでは、Err.Source にコールスタックを格納していきます。

'その他プロシージャ
Option Explicit
Private Const MODULE_NAME	As String = "Module1"

'******************************************************************
'プロシージャ名:  :MyGeneralProcedure
'説明:            :エラー処理に注目
'******************************************************************
Public Sub MyGeneralProcedure()
'============= Declare ==============
'============= Initiarize ===========
On Error GoTo ErrorHandler
    
'============= Main =================
    
    ' 処理...
    
'============= Release ==============
ExitHandler:
    Exit Sub
'============= Error ================
ErrorHandler:
    Call Err.Raise(Err.Number, MODULE_NAME & ".MyGeneralProcedure ← " & Err.Source, Err.Description, Err.HelpFile, Err.HelpContext)
End Sub

こんな感じで、たとえば Class1 というクラスモジュールに MyProperty というプロパティがあり、そのなかで、Module1 という標準モジュールの MyGeneralProcedure をコールしていて、そこで実行時エラーが起こった場合、呼出元に返った時の、Err.Source は、

Class1.MyProperty ← Module1.MyGeneralProcedure ← OriginalErrorSource

のようになります。障害時の追跡に決行役に立つものです。

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/791

コメント

クラスは、MODULE_NAMEとしなくてもTypeName(Me)で
クラス名が取れますよ。標準モジュールはだめです。

>ふぅさん
コメントありがとうございます。
そうですね、フォーム、またはクラスモジュールのみで構築できれば
最も可搬性の高い方法ですね。
残念ながら、VC++ で作成した DLL よりコールバックするようなつくりの多い私の場合は、
標準モジュールを駆逐することはできないです・・・
美しくない・・・

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?