WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Learning the C# Error Handling Mechanism
Pages: 1, 2

Throwing an Exception From a Method

When catching an exception in a method, you have two options in regard to handling the error that occurs inside the method. You can either handle it in the method, and thus quietly catch the exception without notifying the caller, or you can throw the exception back to the caller and let the caller handle it. If you choose the second option, the calling code must catch the exception that is thrown back by the method.



For example, let's say you have a method called GetFileStream, to which you can pass a filepath, which is the path to the file you want to open. The GetFileStream method will try to open the file for you and return the FileStream object of the file. If the file is not found, however, it will throw a FileNotFoundException object, and this exception must be caught by the caller of the GetFileStream function. The code is given in Listing 2.


Listing 2: Throwing back an exception from a method

using System;
using System.IO;

class Testing {

  public FileStream GetFileStream(String filePath) {
    try {
      FileStream fs = File.Open(filePath, FileMode.Open);
      return fs;
    }
    catch (FileNotFoundException e) {
      throw e;
    }
  }

  public static void Main(String[] args) {
    Testing t = new Testing();
    try {
      t.GetFileStream(args[0]);
      Console.WriteLine("Successful");
    }
    catch (FileNotFoundException) {
      Console.WriteLine("File Not Found");
    }
  }
}

After you compile the code, you can run it by typing the program name followed by the path to a file you want to open. For example, this will pass the CompanySecret.txt file on the C drive.

Testing C:\CompanySecret.txt
If the file is found and can be opened, the user will see the "Successful" string on the console. Otherwise, a "File Not Found" error message will be printed.

If you are a Java programmer, note that C# does not have the throws keyword that you normally use in Java to tell the compiler that an exception might be thrown from your method.

Exception Catching Order

Sometimes there can be more than one type of exception that can occur in a try clause. You can catch all of them if you use Exception in the catch clause of your try ... catch block. However, there are cases where you want your code to react differently on different types of exceptions. If this is the case, you then need to provide a catch clause for every exception type that could be thrown. Your code will then look like the following:

try {
// code that could thrown an exception
}
catch (ExceptionType_1 e1) {
  // code that must be run when ExceptionType_1 occurs
}
catch (ExceptionType_2 e2) {
  // code that must be run when ExceptionType_2 occurs
}
.
.
.
catch (ExceptionType_n en) {
  // code that must be run when ExceptionType_n occurs
}

When an exception occurs, the exception is passed up the stack and each catch block is given the opportunity to handle the exception. The order of catch statements is important. You should put catch blocks targeted to specific exceptions before a general exception catch block, or the compiler will issue an error. The proper catch block is determined by matching the type of the exception to the name of the exception specified in the catch block. If there is no specific catch block, then the exception is caught by a general catch block, if one exists. Because sometimes it is very hard to predict all exceptions that can be thrown in all occasions, it is normal practice to use Exception as the type of the last catch clause, like in the following:

try {
// code that could thrown an exception
}
catch (ExceptionType_1 e1) {
  // code that must be run when ExceptionType_1 occurs
}
catch (ExceptionType_2 e2) {
  // code that must be run when ExceptionType_2 occurs
}
.
.
.
catch (ExceptionType_n en) {
  // code that must be run when ExceptionType_n occurs
}

catch (Exception e) {
  // code that must be run when an exception other 
  // than ExceptionType_1 to ExceptionType_n occurs
}

The code in Listing 2 only catches a FileNotFoundException. However, there are other situations where other types of exceptions can also be thrown. For example, if the user does not type in any argument after the program name, then an IndexOutOfRangeException will be thrown. The code in Listing 3 below follows the good practice of trying to catch all predictable exceptions and then using Exception as the last bastion of error handling.

Listing 3: Catching all exceptions

using System;
using System.IO;

class Testing {

  public FileStream GetFileStream(String filePath) {
    try {
      FileStream fs = File.Open(filePath, FileMode.Open);
      return fs;
    }
    catch (FileNotFoundException e) {
      throw e;
    }
  }

  public static void Main(String[] args) {
    Testing t = new Testing();
    try {
      t.GetFileStream(args[0]);
      Console.WriteLine("Successful");
    }
    catch (FileNotFoundException) {
      Console.WriteLine("File Not Found");
    }
    catch (IndexOutOfRangeException) {
      Console.WriteLine("Usage: Testing filepath");
    }
    catch (Exception) {
      Console.WriteLine("Unexpected exception occurs ");
    }

  }
}

Programming C#Programming C#
By Jesse Liberty
July 2001
0-596-00117-7, Order Number: 1177
680 pages, $39.95

Now, your program is more robust. If the user forgets to type in the file path, it won't crash. It will just warn the user that they need to type a file path after the program name. Also, the last catch clause uses Exception as the argument, meaning that any unpredictable exception will also be caught.

Summary

You have seen how C# handles errors in the code using a try ... catch ... finally block. Compared to the older method of checking a function's return value and branching on error, this strategy is superior because it isolated and handled locally.

Budi Kurniawan is a senior J2EE architect and author.



Return to the .NET DevCenter.