Exceptions the VBCorLib Way.
Error handling is a common task for any programmer. Now matter how well you may
design a system, errors are still going to need to be handled.
The VBCorLib library has a wide assortment of Exception classes. How do they
play into the standard On Error handling methods? VBCorLib does not force
exceptions into a programmer's normal style of error handling. Errors can be
raised using the normal mechanism. The classes in VBCorLib do not raise errors
in the normal convention. It does call Err.Raise that can be trapped in
the same way as has always been done. However, VBCorLib does not just raise an error.
The classes in VBCorLib Throw an Exception. This follows how .NET
deals with raising errors. The way that VBCorLib throws an exception is by intantiating
an appropriate Exception derived object and passing it into the public Throw
function. At that point, Throw calls Err.Raise passing in the information
held within the Exception object.
Lets begin with catching a regular error. The function to be used is the Catch
function. This function takes as a parameter an Exception variable, or any
of the other exception classes because they all implement the Exception
interface. In general, the variable should be declared as Exception since it
can handle all derived classes.
Dim ex As Exception
On Error Resume Next
Err.Raise 5,, "A general error."
' Catch returns a boolean indicating if an exception was actually caught.
If Catch(ex, Err) Then
Debug.Print ex.Message
End If
' output
' A general error.
In this example you can see the construct used with Catch. Placed in an
If..Then allows to easily determine if an exception was caught. The Catch
function will set the ex variable to the exception being held inside of
the Catch function. The Err object was passed in this time. It is
an optional parameter and isn't necessary if catching exceptions thrown by VBCorLib.
In this case we are catching one of our own exceptions and the Catch function
has no knowledge of the error. And since errors don't bubble down, Catch
would not be able to retrieve the error from the Err at its level, so it
must be supplied from our level. This is only necessary if the error is being
raised using Err.Raise at this level. If an actual exception object were
to be thrown, then the Err object would not need to be passed to Catch.
In normal error handling, the Err.Number is used to identify a specific
error condition. VBCorLib supplies a broad array of exceptions, each identifying
a specific condition. They still have number associated with them and can be accessed
through the HResult property, if needed.
How can we take advantage of so many exception classes? In the next example will
show a typical way of dealing with exceptions thrown by classes in VBCorLib. We are
going to attempt to open a FileStream object with a file that does not exist. The
FileStream will throw a FileNotFoundException object that we can catch and inspect.
Dim fs As FileStream
On Error Goto CatchIt
Set fs = NewFileStream("MissingFile.txt", FileMode.OpenExisting)
' ... some code
CatchIt:
Dim ex As Exception
If Catch(ex) Then
If TypeOf ex Is FileNotFoundException Then
' deal with a missing file
Dim fex As FileNotFoundException
Set fex = ex
Debug.Print "Could not find file: "; fex.FileName
Else
' deal with other errors
End If
End If
This example shows how to set up an error trap and deal with the different types
of exceptions that could be thrown. The HResult property can be used to
retrieve the error number. The default for FileNotFoundException is 53,
which is what VB would return.
Once catching an exception is accomplished effectively, the next step is to
throw exceptions for specific errors. VBCorLib provides a large set of exception
derived classes that can be used.
Throwing an exception is an easy process. There are a few ways to throw an
exception depending on how much information is to be placed in the object before
it is thrown by VBCorLib. The first method just takes the default settings for
all properties of the exception object. The Throw function is used to get
the error raised and the exception object set for retrieval through Catch.
Throw New Exception
This one line will create a new default Exception object and pass it in to
the Throw function for processing. At that point, the object is set to an
internal variable, then the Err.Raise method is called, passing in the values
from the HResult, Source, and Message properties.
Many times the default values are not specific enough to the situation. A more
specific message can be supplied to an exception object during instantiation.
Some exception classes take additional parameter that are specific to the exception
class being created. The Exception class will require a message to be supplied,
and optionally another exception object, if exceptions are being bubbled up.
' This is a generic exception with a specific message.
Throw Cor.NewException("A more specific message.")
' This is a more specific exception with a specific message and an additional parameter.
Throw Cor.NewArgumentException("Argument is wrong.", "Parameter Name")
The two methods shown show that new objects can be created with full initialization
by using the Cor.* method. The returned exception object is then passed
directly into the Throw function.
Sometimes even more specific information made need to be included in the
exception object. When cases like this arise, then an exception can be created
independantly of the Throw function to allow for additional information
to be set.
Dim ex As Exception
' the exception is created as a local variable to allow for modification
Set ex = Cor.NewException("A specific message.")
' we set an additional property of the exception object
ex.Source = "This method name."
' we now throw the exception to be caught.
Throw ex
Using this approach allows for even more inforamtion to be supplied to the exception.
This additional information will be available by the procedure that catches the
exception, since the same exception object thrown is also retrieved.
Error handling using the mechanism provided by VBCorLib can be very effective
with dealing with specific information. It allows for the bubbling of errors
from lower functions to higher functions. Exception object can also be stored
and retrieved as normal objects. They are also persitable and work with the PropertyBag.
This tutorial shows some of the possibilities of using the VBCorLib exception
framework in conjunction to the standard VB error routines. The VBCorLib classes
always throw an exception using this mechanism, so an exception object can be
retrieved using Catch or the VB Err object can be used as normal to
respond to a VBCorLib thrown exception.
|