Previous section   Next section

Chapter 11. Exceptions

VB.NET handles errors and abnormal conditions with exceptions. An exception is an object that encapsulates information about an unusual program oCcurrence, such as running out of memory or losing a network connection.

It is important to distinguish exceptions from bugs and errors. A bug is a programmer mistake that should be fixed before the code is shipped. An exception is not the result of a programmer mistake (though such mistakes can also raise exceptions). Rather, exceptions are raised as a result of predictable but unpreventable problems that arise while your program is running (e.g., a network connection is dropped or you run out of disk space).

An error is caused by user action. For example, the user might enter a number where a letter is expected. Once again, an error might cause an exception, but you can prevent that by implementing code to validate user input. Whenever possible, user errors should be anticipated and prevented.

Even if you remove all bugs and anticipate all user errors, you will still run into unavoidable problems, such as running out of memory or attempting to open a file that no longer exists. These are exceptions. You cannot prevent exceptions, but you can handle them so that they do not bring down your program.

When your program encounters an exceptional circumstance, such as running out of memory, it throws (or "raises") an exception. You might throw an exception in your own methods (for example, if you realize that an invalid parameter has been provided) or an exception might be thrown in a class provided by the Framework Class Library (for example, if you try to write to a read-only file). Many exceptions are thrown at runtime when the program can no longer continue due to an operating system problem (such as a security violation). Exceptions must be handled before the program can continue.

You provide for the possibility of exceptions by adding try/catch blocks in your program. The catch blocks are also called exception handlers. The idea is that you try potentially dangerous code, and if an exception is thrown you catch (or handle) the exception in your catch block.

VB.NET also provides unstructured exception handling through the use of Error , On Error, and Resume statements. This approach is not object-oriented, and not consistent with how exceptions are handled in other .NET languages. Thus it is discouraged and not shown in this book.

Ideally, if the exception is caught and handled, the program can fix the problem and continue. Even if your program can't continue, by catching the exception you have an opportunity to print a meaningful error message and terminate gracefully.

When an exception is thrown, execution of the current function halts and the Common Language Runtime (CLR) searches back through the stack until an appropriate exception handler is found. The search for an exception handler can "unwind the stack." This means that if the currently running function does not handle the exception, the current function will terminate and the calling function will get a chance to handle the exception. If none of the calling functions handles it, the exception will ultimately be handled by the CLR, which will abruptly terminate your program.

If Function A calls Function B and Function B calls Function C, these function calls are all placed on the stack (an area of memory set aside for local variables). When a programmer talks about "unwinding the stack," what is meant is that you back up from C to B to A, as illustrated in Figure 11-1.

Figure 11-1. Unwinding the stack
figs/pvn2_1101.gif

If you must unwind the stack from C to B to A to handle the exception, when you are done you are in A; there is no automatic return to C.

If you return all the way to the first method and no exception handler is found, the default exception handler (provided by the compiler) just terminates the program.


  Previous section   Next section
Top