1. When throwing exceptions, always include the source exception if one exists, by setting the InnerException property.
You never know how an exception is going to be dealt with at higher levels, so it is best to provide as much information as possible regarding the state and cause of the exception.
Catch e As Exception
Throw New ApplicationException("Uh oh...", e)
Practice 5, below, shows you how to access and use this InnerException at higher levels
2. Uniquely identify error locations in code, and group into types.
This will allow a link from the ultimate destination of the error message (e.g. the Event Log) back to source code. The simplest way to do this is to share an enum with all source code that provides a code lookup, which I call EventID:
Public Enum EventID As Integer
DATA_ERROR = 1
FILE_ACCESS_ERROR = 2
REGISTRY_ACCESS_ERROR = 3
FTP_AUTHENTINCATION_FAILURE = 4
FTP_UNKNOWN = 5
LOG_ERROR_UNKNOWN = 6
SYSTEM_CONFIG_MISSING_ARGS = 7
SYSTEM_INFORMATION = 8
ZIP_OPERATION_FAILURE = 9
3. Identify the importance of the error
Basically, you need to decide if the error encountered is going to stop the program from doing what it is expected to do. There are three possible values that indicate error importance: critical, warning, and information. Again, the simplest way to identify this is to share an enum, which I call EventImportance:
Public Enum EventImportance As Short
Critical = 1
Information = 2
Warning = 3
Here is an example of the distinction:
|A network error is encountered because a required path cannot be found. This could mean that the task will never be completed because the application does not have access to read the directory, in which case the error is critical. It could also mean that the operation timed out because of heavy traffic but would presumably succeed on a subsequent pass, in which case the error is a warning (perhaps something could be done administratively to resolve the issue, perhaps not). However, the path may be unavailable simply because it has been removed and is no longer required, in which case the error is purely informational.|
Note: you could use the .NET system enumeration System.Diagnostics.EventLogEntryType here, although it might be more flexible to support your own custom enumeration.
4. Act according to the urgency of the error
Urgency is whether or not the program can continue to function in light of the error encountered. This is generally independent of the importance, and it is this issue that will dictate how you handle the error.
- If an error is urgent, it needs to be raised so that the current process stops, or at least handles it at a higher level.
- If not, it can be logged (according to its importance) and processing can continue.