Often when writing a specialized class, you'll want it to raise its own specific errors, and you'll want a clean way for user/calling code to handle these custom errors. A neat way to achieve this is by defining a dedicated Enum
type:
Option Explicit
Public Enum FoobarError
Err_FooWasNotBarred = vbObjectError + 1024
Err_BarNotInitialized
Err_SomethingElseHappened
End Enum
Using the vbObjectError
built-in constant ensures the custom error codes don't overlap with reserved/existing error codes. Only the first enum value needs to be explicitly specified, for the underlying value of each Enum
member is 1
greater than the previous member, so the underlying value of Err_BarNotInitialized
is implicitly vbObjectError + 1025
.
A runtime error can be raised using the Err.Raise
statement, so the custom Err_FooWasNotBarred
error can be raised as follows:
Err.Raise Err_FooWasNotBarred
The Err.Raise
method can also take custom Description
and Source
parameters - for this reason it's a good idea to also define constants to hold each custom error's description:
Private Const Msg_FooWasNotBarred As String = "The foo was not barred."
Private Const Msg_BarNotInitialized As String = "The bar was not initialized."
And then create a dedicated private method to raise each error:
Private Sub OnFooWasNotBarredError(ByVal source As String)
Err.Raise Err_FooWasNotBarred, source, Msg_FooWasNotBarred
End Sub
Private Sub OnBarNotInitializedError(ByVal source As String)
Err.Raise Err_BarNotInitialized, source, Msg_BarNotInitialized
End Sub
The class' implementation can then simply call these specialized procedures to raise the error:
Public Sub DoSomething()
'raises the custom 'BarNotInitialized' error with "DoSomething" as the source:
If Me.Bar Is Nothing Then OnBarNotInitializedError "DoSomething"
'...
End Sub
The client code can then handle Err_BarNotInitialized
as it would any other error, inside its own error-handling subroutine.
Note: the legacy Error
keyword can also be used in place of Err.Raise
, but it's obsolete/deprecated.