|
Here are two classes which can help with handling errors within an
application.
The first one is CErr. This class is a
wrapper for the standard Err object. Since it is a wrapper the class does need
to be included in the project. Attempting to put it inside a DLL will result in
the wrong VB6A.Err object being used.
The second one is CerrStack.
This provides a simple stack so that CErr instances can be Pushed and Popped -
to save error state. Push and Pop can prove useful in more complex Error
handlers.
The final one is CGuiErr. This is a GUI
version of CErr. The main difference is that it has a Show method which will
display an error form. The GUI version will also use a resource file to
translate the error text into a piece of text suitable for a user. Any tokens in
the user text will be replaced with the values raised up as part of the error
message.
Unfortunately, CGUIErr and CErr do overlap in functionality and would need to
be kept in step if you perform any maintenance on them. This is due to the fact
that you have to be very careful not to reset the Error number and description.
Calling a subroutine will certainly do this...
All of these classes are in Cerr.Zip
(10k) together with a sample application.
Using CErr (or CGUIErr)
CErr is a direct replacement for the Err class. This sample piece of code
shows how it can be used and what the outputs are. As an aside, this is one time
when the use of 'As New' is a good idea - the alternative is to instantiate an
object that may never be used.
- Private Err As New CErr
Option Explicit
Sub Main()
8 On Error Resume Next
9 Call Proc1
12 Err.Show ProcName := "Merrtest.Proc1"
- End Sub
Sub Proc1()
17 On Error GoTo ErrHandler
18 Proc2
19 Exit Sub
21 ErrHandler:
22 Err.Raise Procname:= "Merrtest.Proc1"
- End Sub
Sub Proc2()
26 On Error GoTo ErrHandler
27 Proc3
28 Exit Sub
30 ErrHandler:
31 Err.Raise ProcName:="Merrtest.Proc2"
End Sub
Sub Proc3()
35 On Error GoTo ErrHandler
37 Err.RaiseEx vbObjectError + 5, "Weird stuff
%1", 1, 2, "Carrot"
38 Exit Sub
40 ErrHandler:
41 Err.Raise ProcName:="Merrtest.Proc3"
End Sub
The Err.Description Output will look like this:
- Merrtest.Proc1 Line=18
Merrtest.Proc2 Line=27
Merrtest.Proc3 Line=37
Merrtest.Proc3
Err=vbObjectError+5
Description=Weird stuff %1
Values=1|2|Carrot
Clearly the output is designed for use by a developer to debug an
application. As discussed in the Error Handling section
the raw description would not be shown to the user. Instead, the Err.Number
would be used to retrieve a string from a resource file or a database. This
string would be shown to the user. The list of values could then be parsed and
placed into the description to produce something more friendly. CGuiErr
will do this all for you automatically.
It is very important for maintenance that the source of the raised error only
provide the error number and perhaps a list of values to be substituted
into the message. Coding the description - whether as a constant or as text is a
very bad idea and produces high-maintenance code. Likewise, doing the parsing
yourself is also high maintenance.
RaiseEx is an enhanced version of Raise which can be used to
raise a number, a description and a list of values which can be substituted into
a string. A description is allowed for the developer to add a helpful
comment, it is not meant to be used for user text.
Note: Any error will be trapped and raised up by this handler. I have
used RaiseEx to demonstrate how it can be used. If it is replaced by 'Debug.Print
1/0' then this is what you will get:
- Merrtest.Proc1 Line=15
Merrtest.Proc2 Line=24
Merrtest.Proc3 Line=33
Err=11
Description=Division by zero
Show - which is only available on CGUIErr will format the
results and use the form to display a meaningful message to the user.
Log - which is available on both CErr and CGUIErr is used for
those times when it is not possible to raise an error up - because you are in an
event - and it is not viable to display an error dialog.
|