Runtime Error Handling VB.NET

As we have mentioned, VB currently supports both unstructured and structured error handling. Let us first look at unstructured error handling.

Unstructured Error Handling

Error-handling techniques that revolve around the various On Error... statements are referred to as unstructured error-handling techniques. These techniques generally use the Err object and the Visual Basic call stack.

The Err object

Visual Basic's built-in error object, called Err, is one of the main tools for unstructured error handling. This object has several properties and methods, as shown in Tables.

Table : Properties of the Err object

Properties of the Err object

Table : Methods of the Err object

Methods of the Err object

Dealing with runtime errors

Visual Basic detects a runtime error as soon as it occurs, sets the properties of the Err object, and directs the flow of execution to a location that the programmer has specified by the most recent On Error... line. This location can be one of the following:

  • The line of code immediately following the line that caused the error.
  • Another location within the offending procedure.
  • The procedure that called the offending procedure, if there is one. If not, VB issues an error message itself and terminates the application.

Let us take a closer look at each of these possibilities.

  • In-line error handling
  • Code execution will be "redirected" to the line following the offending line of code (that is, execution will continue immediately following the offending line) if the most recent preceding On Error statement is:

    On Error Resume Next

    This is referred to as in-line error handling. Here is an example that involves renaming a file. Note the typical use of a Select Case statement to handle the error based on the value of Err.Number. Incidentally, one way to obtain error numbers is to deliberately invoke a particular error and break execution (with a breakpoint) to examine Err.Number:

  • Centralized error handling
  • While in-line error handling does have its uses, there is much to be said for centralizing error handling within a procedure. (This often improves readability and makes code maintenance easier.) We can direct code execution to a central error handler using the code:

    On Error Goto label

    This is outlined in the following code shell: Once the On Error Goto label line is executed, we say that the error handler beginning at the label ErrHandler is active.

    Once code execution is directed to the error handler, there are several possibilities for dealing with the error. The most common possibility is simply to handle the error in the active error handler, perhaps by displaying an error message asking the user to take corrective action.

    Another common (and useful) approach is passing information about an error to the calling procedure with parameters or with the return value of the offending function. For instance, if a function is designed to rename a file, the function might return an integer error code indicating the success or failure of the operation. This is quite common among the Win32 API functions. In particular, the error code might be 0 for success, -1 if the file does not exist, -2 if the new filename is invalid, and so on. A third possibility is to pass the error to the calling procedure by invoking the Err.Raise method within the active error handler, as in:

    This triggers the calling procedure's error handler (or more precisely, the next enabled error handler in the calls list). This process is called regenerating or reraising the error.

    Note that it is possible to deactivate an active error handler using the line:

    If there is no active error handler, then VB reacts to errors just as though no error handler existed in the procedure. We describe this situation in the next section.

  • No enabled error-handler
  • If there is no enabled error handler in the offending procedure, either because there is no OnError statement in the procedure or because error handling has been disabled with an On Error Goto 0 statement, then Visual Basic automatically sends the error to the calling procedure's error handler. If the calling procedure has no error handler, the error continues up the calls list until it reaches an enabled error handler. If none is found, then Visual Basic handles the error by displaying an error message and terminating the application.

Structured Exception Handling

Structured exception handling uses a Try...Catch...Finally structure to handle errors. As we will see, VB .NET's structured exception handling is a much more object-oriented approach, involving objects of the Exception class and its derived classes.


The syntax of the Try...Catch...Finally construct is given here:

The tryStatements (which are required) constitute the Try block and are the statements that are monitored for errors by VB. Within the Try block, we say that error handling is active.

The Catch blocks (of which there can be more than one) contain code that is executed in response to VB "catching" a particular type of error within the Try block. Thus, the Catch blocks consist of the error handlers for the Try block.

The phrases exception [As type] and [When expression] are referred to as filters in the VB .NET documentation. In the former case, exception is either a variable of type Exception, which is the base class that "catches" all exceptions, or a variable of one of Exception's derived classes. (We provide a list of these classes a bit later.) For instance, the variable declared as:

Catch e As Exception

will catch (that is, handle) any exception. The variable declared as:

catches (handles) any exception of class ArgumentNullException. In short, type is the name of one of the exception classes.

The When filter is typically used with user-defined errors. For instance, the code in the following Try block raises an error if the user does not enter a number. The Catch block catches this error:

does not work (that is, the Catch statements are never executed) because no error was generated. The Exit Try statement is used to break out of any portion of a Try...Catch...Finally block. The optional finallyStatements code block is executed regardless of whether an error occurs (or is caught), unless an Exit Try statement is executed. This final code can be used for cleanup in the event of an error. (By placing an Exit Try at the end of the Try block, the finallyStatements are not executed if no error occurs.)

As with unstructured error handling, VB may pass an error up the call stack when using structured error handling. This happens in the following situations:

  • If an error occurs within a Try block that is not handled by an existing Catch block
  • If an error occurs outside any Try block (provided, of course, that no On Error-style error handlers are active).
  • Exception classes

The System namespace contains the Exception class, which is the base class for a substantial collection of derived exception classes, listed as follows. Note that the indentation indicates class inheritance. For example, EntryPointNotFoundException (the fifth from the last entry in the list) inherits from TypeLoadException.

As Microsoft states: "Most of the exception classes that inherit from Exception do not implement additional members or provide additional functionality." Thus, it is simply the class name that distinguishes one type of exception from another. The properties and methods applied to an exception object are inherited from the Exception base class.

When writing Catch blocks, we always face the question of whether to simply trap the generic exception class, as in:

or whether to trap specific exception classes. Of course, the time to trap specific exception classes is when we want to handle errors differently based on their class. For instance, this may take the form of issuing different custom error messages for different exception types.

Also, there are occasions when we may want to take advantage of members of a particular exception class that are not implemented in the Exception base class. For instance, the ArgumentException class has a ParamName property that returns the name of the parameter that causes the exception. Now, if we simply trap the generic Exception class, as in the following code:

then we cannot take advantage of the ParamName property. On the other hand, if we specifically trap the ArgumentException class, as in the following code:

then we can retrieve the name of the offending parameter. Now let us take a look at some of the members of the Exception class:

Message property
A string containing an error message.

Source property
A string that describes the application or object that threw the exception.

StackTrace property
A string that contains the stack trace immediately before the exception was thrown. We provide an example of this in a moment.

TargetSite property
A string that gives the method that threw the exception.

ToString method
A string that returns the fully qualified name of the exception, possibly the error message, the name of the inner exception, and the stack trace. Its syntax is simply:

ToString( )

The best way to get a feel for these members is with an example. Consider the following code, which consists of three subroutines. The first subroutine, Exception0, contains a Try...Catch... statement. In the Try code block, the subroutine Exception0 calls the subroutine Exception1, which simply calls Exception2.

In Exception2, there is a single line of code that executes the Throw statement, which throws an exception. This is similar to raising an error with the Err.Raise method. However, as you can see by the New keyword, the Throw statement actually creates an object of one of the exception types. The output from the call to Exception0 is:

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd Protection Status

VB.NET Topics