Tuesday, April 16, 2024 04:27

Table of contents >> Debugging And Error Handling > Exceptions


In an ideal world, a computer program will execute anything the programmer intended, the way the programmer intended. But since we don’t live in an ideal world (sadly), there are moments when due to the programmer’s mistake or to external conditions, these programs will malfunction or function in a way not intended, causing an exception from what we would normally expect.

An exception is a signal from the software that something disrupted its normal execution. For instance, we might want to download a file from a server. But halfway through, the internet connection goes down and the download cannot continue. This is considered an exception.

Although most beginner programmers fear and loath exceptions, experience teaches us that they are mere tools that can help us in detecting, interacting and correcting abnormal behaviors. When an exception occurs, the current state of the program is saved, the execution is halted and the control is passed to an exception handler, if such thing exist in that context. Exceptions are accompanied by an error message which can help us identify what went wrong in the program. Programmers say that an exception is raised or thrown.

Exception handlers are programming mechanisms that allow the program to throw exceptions and catch them. In procedural programming, methods and functions usually return a value which can be used for error signaling. In OOP, exceptions offer a better way of dealing with errors, and consequently, methods and functions are able to throw and catch errors themselves, or to pass the exception to the method that called them. This allows errors to be propagated higher in the execution stack and hence make the code much more flexible. Another good thing in OOP is that exceptions are actually classes, and such we can have exceptions hierarchies. We haven’t yet learned about inheritance, but suffice to say that when an exception is handled (caught), the handling mechanism could catch a whole class of exceptions and not just a particular error (as in the traditional procedural programming). In other words, we can catch multiple types of errors at the same time, in a centralized manner.

Exceptions are objects. They describe the error, offer information about it, show the place in the program where the error occurred and the state of the program when that error occurred. Each exception in .NET contains the so-called stack trace, which gives information of where exactly the error occurred. This will be discussed in more details later on.

Lets take an example of a code that will throw an exception:

The above code will try to read a file from the disk, at a path we are providing as an argument to the function that performs the reading. We haven’t learned about dealing with files yet, but it is OK for the moment. The compiler will not complain about any errors, because there are none. For what its worth, from the compiler’s perspective, there is nothing wrong with that code. However, when we try to run this program from Windows Explorer, the output will look like this:

Trying to run the code from within Visual Studio will generate the same exception, but the behavior will be different. Visual Studio will actually show us the occurring exception:



If this program was a GUI application, the runtime behavior would be different again. We would get this:

and we probably all know what that means…

The problem was that there is no file at the path we provided to that method. And this generates an exception. Another thing that we observe from the above photos is the fact that the compiler not only shows us the line at which the error occurred, but it also shows us details about the error, such as its name and some description about it. We now know that there are more than one type of exceptions and they have names. The most frequent exceptions that you will encounter as a programmer are the following:

AccessViolationException – The exception that is thrown when there is an attempt to read or write protected memory.
ApplicationException – The exception that is thrown when a non-fatal application error occurs.
ArgumentException – The exception that is thrown when one of the arguments provided to a method is not valid.
ArgumentNullException – The exception that is thrown when a null reference is passed to a method that does not accept it as a valid argument.
ArgumentOutOfRangeException – The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the called method.
ArithmeticException – The exception that is thrown for errors in an arithmetic, casting, or conversion operation.
DivideByZeroException – The exception that is thrown when there is an attempt to divide an integral or decimal value by zero.
DllNotFoundException – The exception that is thrown when a DLL specified in a DLL import cannot be found.
IndexOutOfRangeException – The exception that is thrown when an attempt is made to access an element of an array with an index that is outside the bounds of the array.
InsufficientMemoryException – The exception that is thrown when a check for sufficient available memory fails. This class cannot be inherited.
InvalidCastException – The exception that is thrown for invalid casting or explicit conversion.
NotFiniteNumberException – The exception that is thrown when a floating-point value is positive infinity, negative infinity, or Not-a-Number (NaN).
NullReferenceException – The exception that is thrown when there is an attempt to dereference a null object reference.
ObjectDisposedException – The exception that is thrown when an operation is performed on a disposed object.
OutOfMemoryException – The exception that is thrown when there is not enough memory to continue the execution of a program.
OverflowException – The exception that is thrown when an arithmetic, casting, or conversion operation in a checked context results in an overflow.
StackOverflowException – The exception that is thrown when the execution stack overflows because it contains too many nested method calls.
TimeoutException – The exception that is thrown when the time allotted for a process or operation has expired.
UnauthorizedAccessException – The exception that is thrown when the operating system denies access because of an input/output (I/O) error or a specific type of security error.
KeyNotFoundException – The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.
DirectoryNotFoundException – The exception that is thrown when part of a file or directory cannot be found.
DriveNotFoundException – The exception that is thrown when trying to access a drive or share that is not available.
EndOfStreamException – The exception that is thrown when reading is attempted past the end of a stream.
FileNotFoundException – The exception that is thrown when an attempt to access a file that does not exist on disk fails.
IOException – The exception that is thrown when an I/O error occurs.
PathTooLongException – The exception that is thrown when a path name or filename is longer than the system-defined maximum length.
COMException – The exception that is thrown when an unrecognized HRESULT is returned from a COM method call.
InvalidComObjectException – The exception thrown when an invalid COM object is used.
SerializationException – The exception thrown when an error occurs during serialization or deserialization.
SecurityException – The exception that is thrown when a security error is detected.
XmlSyntaxException – The exception that is thrown when there is a syntax error in XML parsing. This class cannot be inherited.
HttpException – Describes an exception that occurred during the processing of HTTP requests.
HttpParseException – The exception that is thrown when a parse error occurs.
SocketException – The exception that is thrown when a socket error occurs.

You don’t need to memorize this list, just keep it as a reference whenever you encounter exceptions.

In the next lesson, we will talk about handling exceptions, so they don’t break our programs when they occur, and put them to good use for us.

Tags: , ,

Leave a Reply

Follow the white rabbit