Sams Teach Yourself Visual Studio .NET 2003 in 21 Days

Sams Teach Yourself .Net in 21 Days

By Jason Beres

Using Structured Exception Handling

SEH is the control of flow syntax that you use to handle exceptions. SEH isn't a new concept to C++ developers, but it's quite different from the unstructured exception handling mechanism used in previous versions of Visual Basic. The idea behind SEH is that you write code to handle specific or nonspecific errors that could occur as a result of user input, resource availability, or a generic problem that might occur in functions you're writing. With SEH, you can write code to handle errors for specific lines of code; you aren't limited to writing an error-handling routine for a complete subprocedure or function as you were in Visual Basic 6.

You write SEH code using Try/Catch/Finally blocks in Visual Basic .NET and C#. Using Try/Catch/Finally means you're using structured exception handling.

Handling Exceptions with Try/Catch/Finally

The syntax for Try/Catch/Finally blocks can be explained with the following rules:

In layman's terms, you're trying to execute some code, catching an error if one occurs, and finally doing something when the code succeeds or fails. The following Visual Basic .NET and C# syntax will give you an idea of what a Try/Catch/Finally block might look like:

vbnet_icon.gif
Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

  Try
    ' This is code you are attempting to execute
  Catch
    ' This is code that executes if an exception occurs
  Finally
    ' This is code that runs after the Try or Catch statements
  End Try

End Sub

c_icon.gif
private void Form1_Load(object sender, System.EventArgs e)
{
    try
    {
        // This is code you are attempting to execute
    }
    catch
    {
        // This is code that executes if an exception occurs
    }
    finally
    {
        // This is code that runs after the Try or Catch statements
    }
}

Understanding the Catch Statement

The Catch statement filters exceptions based on the code executed in the Try statement. There are a few ways to handle Catch statements:

To see this in action, create a new Windows Forms project called Exceptions, and add two TextBox controls and a two-button control to the default form. Make sure the Text property of the TextBox controls is blank. Your form should look like Figure 7.4.

07fig04.jpg

Figure 7.4 Default Form1 for the Exceptions project.

Now you're going to add some code that causes exceptions to occur so that you can see the behavior and learn how to handle both a single exception and multiple exception cases. You also learn how the Finally statement works.

In the code-behind for the Button1_Click event, you write code that attempts to delete the file that's typed into the textbox1 control. Listing 7.1 shows what the code-behind should look like.

Example 7.1. Code-Behind for the Button1_Click Event

vbnet_icon.gif
Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

  Try
    System.IO.File.Delete(TextBox1.Text)
  Catch
    MsgBox("An exception occurred!")
  Finally
    MsgBox("Finally we are done!")
  End Try

End Sub

c_icon.gif
private void button1_Click(object sender, System.EventArgs e)
{
    try
    {
        System.IO.File.Delete(textBox1.Text);
    }
    catch
    {
        MessageBox.Show("An Exception Occurred");
    }
    finally
    {
        MessageBox.Show("Finally we are done!");
    }
}

When you run the code, you get two message box prompts. The first one lets you know that an error occurred, and the second one lets you know that the code is finally done. To break it down, here's exactly what happened:

You can see that the Catch statement executed correctly, but why did the Finally statement execute also? Because in SEH, the Finally statement always executes—no matter what. Even if no exception is thrown, the Finally statement code executes. This is useful for cleaning up any resources that you used in the Try statement. For example, if you opened a file stream or database connection, you know that you need to close that resource, so you can always put that type of resource cleanup code in the Finally statement.

How to Filter Specific Exceptions

In the previous example, you used a generic Catch statement to get information about the last error that occurred. But there will be many times when you'll want to react to a specific error that occurred. In such cases, you can use the Catch As statement. When you use Catch As, you're filtering the exception handling based on a specific exception class. Listing 7.2 enhances the code from Listing 7.1 to look for a specific exception object.

Example 7.2. Enhanced Code Utilizing the Catch As Statement

vbnet_icon.gif
Try

  System.IO.File.Delete(TextBox1.Text)

Catch ex1 As System.IO.FileNotFoundException

  MessageBox.Show("File is not found")
  MessageBox.Show(ex1.Message)

Catch ex2 As System.IO.PathTooLongException

  MessageBox.Show("Path is too long")
  MessageBox.Show(ex2.Message)

Catch ex3 As System.IO.DirectoryNotFoundException

  MessageBox.Show("Directory Not Found")
  MessageBox.Show(ex3.Message)

Catch ex As System.Exception

  MessageBox.Show("This is a generic exception handler")

Finally

  MessageBox.Show("Finally we are done!")

End Try

c_icon.gif
try
{
    System.IO.File.Delete(textBox1.Text);
}
catch (System.IO.FileNotFoundException ex1)
{
    MessageBox.Show("File is not found");
    MessageBox.Show(ex1.Message);
}
catch (System.IO.PathTooLongException ex2)
{
    MessageBox.Show("Path is too long");
    MessageBox.Show(ex2.Message);
}
catch (System.IO.DirectoryNotFoundException ex3)
{
    MessageBox.Show("Directory not found!");
    MessageBox.Show(ex3.Message);
}
catch (System.Exception e)
{
    MessageBox.Show("This is a generic exception handler");
}
finally
{
    MessageBox.Show("Finally we are done!");
}

When you run this code now, type in an invalid filename in Textbox1, and then click the Delete File button. The Output window will have the following message:

Directory Not Found
Could not find a part of the path "D:\MyText.txt".

When the error occurs and the exception is thrown, the first Catch statement that has the handler for the particular thrown exception executes. For this reason, you must always attempt to catch in order from the most specific exception to the least specific exception. If the more specific Catch statements can't handle the exception, you always have the generic System.Exception fallback exception handler.

In the .NET Framework class library (FCL), each class has specific exception classes that define what could possibly go wrong when using that class. Those are the Exception classes derived from System.Exception. So, how do you know what exceptions can occur when? If you look up the File.Delete method in the .NET Framework SDK, you'll see not only how to use the syntax for File.Delete, but also the exceptions that can be thrown from using the File.Delete method. Figure 7.5 gives you an idea of what to look for when trying to figure what exceptions can occur in a class.

07fig05.jpg

Figure 7.5 .NET SDK help file for the File.Delete method showing exceptions.

Using Visual Basic. NET Exception-Handling Extensions

Visual Basic .NET has two extensions that you can use to handle exceptions: the Catch When and Exit Try statements.

The Catch When statement can be used to look for other criteria besides the exception information—possibly a variable value or a condition of the exception itself. The Exit Try statement simply exits the Try statement at a certain point. Listing 7.3 shows how to use the Catch When and Exit Try statements.

Example 7.3. Using Catch When and Exit Try

vbnet_icon.gif
Dim x As Integer = 5

Try

  System.IO.File.Delete(TextBox1.Text)

Catch ex As System.Exception When x = 7

  MessageBox.Show("Please fill in a filename to delete")

Catch ex1 As Exception When x = 5

  If Today.Date = "7/29/2002" Then
    Exit Try
  End If

  MessageBox.Show("You are level 5")

Finally

  MessageBox.Show("Done!")

End Try

The first thing Listing 7.3 does is create an integer variable named x, and set it to a value of 5. There are generic exception handlers in the Try/Catch block, but the When clause tests for the value of x. Because x = 5, you're prompted with You are level 5. If you happen to change your system date to 7/29/2002 and rerun the code, you'll never get the You are level 5 prompt, because the Exit Try statement executes before the next line of code.

Up to this point, you've learned everything you need to know about handling exceptions in .NET with structured exception handling. Now you'll see how to use the tools in Visual Studio .NET to effectively debug your code before you deploy it so that you can avoid exceptions.

Raising an Exception

In Visual Basic 6, you could use the Err.Raise statement to raise an error to your applications. In .NET, you Throw an Exception to your application. When you need to cause an error based on the state of your application, you use the Throw statement with a new instance of the appropriate exception class. The following code demonstrates how to Throw a new Exception based on the Boolean return value of the File.Exists method:

vbnet_icon.gif
Try
  If Not Directory.Exists("D:\Test") Then
    Throw New DirectoryNotFoundException()
  End If
Catch ex As Exception
  MessageBox.Show(ex.Message)
End Try

c_icon.gif

try
{
 if (!Directory.Exists(@"D:\Test"))
  {
   throw new DirectoryNotFoundException();
  }

}
  catch (System.Exception ex)
  {
   MessageBox.Show(ex.Message);
  }

finally
{

}

Share ThisShare This

Informit Network