C Sharp

The Benefits of Exception Handling Over Return Codes

When using return codes, the called method returns an error code and the error condition is handled by the calling method. Because the error handling occurs outside the scope of the called method, there is no guarantee that the caller will check the returned error code. As an example, let's say that you write a class called CommaDelimitedFile that wraps the functionality of reading and writing standard comma-delimited files. Part of what your class would have to expose includes methods to open and read data from the file. Using the older return code method of reporting errors, these methods would return some variable type that would have to be checked by the caller to verify the success of the method call. If the user of your class called the CommaDelimitedFile.Open method and then attempted to call the CommaDelimitedFile.Read method without checking whether the Open call succeeded, this could-and probably would in the case of a demo in front of your most important client-cause less than desirable results. However, if the class's Open method throws an exception, the caller would be forced to deal with the fact that the Open method failed. This is because each time a method throws an exception, control is passed back up the call stack until it's caught. Here's an example of what that code might look like: -

using System;
class ThrowException2App
{
    class CommaDelimitedFile
    {
        protected string fileName;
        public void Open(string fileName)
        {
            this.fileName = fileName;
            // Attempt to open file
            // and throw exception upon error condition.
            throw new Exception("open failed");
        }
        public bool Read(string record)
        {
            // Code to read file.
            return false; // EOF
        }
    }
    public static void Main()
    {
        try
        {
            Console.WriteLine("attempting to open file");
            CommaDelimitedFile file = new CommaDelimitedFile();
            file.Open("c:\\test.csv");
            string record = "";
            Console.WriteLine("reading from file");
            while (file.Read(record) == true)
            {
                Console.WriteLine(record);
            }
            Console.WriteLine("finished reading file");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

In this example, if either the CommaDelimitedFile.Open method or the CommaDelimitedFile.Read method throws an exception, the calling method is forced to deal with it. If the calling method does not catch the exception and no other method in the current code path attempts to catch an exception of this type, the application will abort. Pay particular attention to the fact that because the Open method call is placed in a block, an invalid read (using our example in which the Open method has thrown an exception) would not be attempted. This is because programmatic control would be passed from the Open call in the try block to the first line of the catch block. Therefore, one of the biggest benefits of exception handling over return codes is that exceptions are programmatically more difficult to ignore.