[C# Helper]
Index Books FAQ Contact About Rod
[Beginning Database Design Solutions, Second Edition]

[Beginning Software Engineering, Second Edition]

[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

[C# 24-Hour Trainer]

[C# 5.0 Programmer's Reference]

[MCSD Certification Toolkit (Exam 70-483): Programming in C#]

Title: Use try catch blocks to protect against unexpected errors in C#


Most programs cannot anticipate every possible error. You can watch for things like missing files, but it's hard to stop a determined user from entering "ten" in a TextBox that should contain a number. (Actually you can prevent that by using a NumericUpDown, Slider, ComboBox, or other control instead of a TextBox, but those controls don't work well if the user must enter values that spam a huge range.)

In cases where you cannot predict all possible errors, you can use a try catch block. Place the code that could fail inside the try part. Then use one or more catch sections to handle any errors that occur. An optional exception variable can gather information about the error for your catch code to use in determining what went wrong and what you should do about it.

In this program, when you enter two integers X and Y and click the Calculate button, the program divides X by Y. Enter the value "ten" to cause a formatting error. Enter 0 for Y to cause a divide by zero error.

The following code shows how the program performs the calculation.

// Perform the calculation. private void btnCalculate_Click(object sender, EventArgs e) { // Clear the result (in case the calculation fails). txtResult.Clear(); try { // Perform the operations that might fail. int x = int.Parse(txtX.Text); int y = int.Parse(txtY.Text); float result = x / y; txtResult.Text = result.ToString(); } catch (FormatException) { // A formatting error occurred. // Report the error to the user. MessageBox.Show( "The input values must be integers.", "Invalid Input Values", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { // Some other error occurred. // Report the error to the user. MessageBox.Show(ex.Message, "Calculation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // Record the kind of exception class // so we can catch it specifically. Console.WriteLine(ex.GetType().Name); } finally { MessageBox.Show("Done", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information); } }

Notice that the code first clears the result or its previous calculation. That way if the code fails before it displays a new result, the user doesn't see the old result.

The try block contains the code that could fail. The first catch block looks specifically for FormatException errors, which occur if you enter a value such as "ten." This block does not use the FormatException object that represents the error so it only declares the error's type and doesn't make a variable for it.

The next catch block looks for any exception object. All exception classes inherit from the Exception class, so this block will catch any exception that was not caught by an earlier catch block.

The code continues trying catch blocks until it finds one that matches the exception that was raised or it runs out of catch blocks (in which case it does nothing).

After it has executed any catch blocks, the program executes the code in the finally block (if there is one). Note that this code executes no matter how the program leaves the try catch block. For example:

  • If the try block has no error, the finally block executes when it is done.
  • If the try block executes a return statement, the finally block executes before the code returns.
  • If a catch block executes, the finally block executes when it is done.

Usually the finally block is used to perform cleanup chores such as closing databases, deleting temporary files, and performing other tasks that should take place whether or not the rest of the code succeeds.

A couple of final notes:

  • You must include at least one catch block or a finally block. You don't need both and they don't need to contain any code.
  • If a catch block should catch all exceptions and you don't need it to use the exception object, you don't need to declare it. For example:

    catch { ... }

  • The catch blocks are tested in order so you should put the more specific exception classes first and more general exceptions such as Exception later.
  • The try catch block doesn't give you an easy way to simply ignore all exceptions. You need to use a separate try catch block for every statement that you want to execute while ignoring errors.
  • Often you can make your code easier to read by putting the dangerous code in a separate method and then invoking it in a try catch block.
  • You can use the throw statement to throw an exception.
  • To re-throw the current exception, use the throw statement without any parameters. That lets any higher-level try catch block handle the error.
  • You should always use a try catch block when you parse user input.

Download the example to experiment with it and to see additional details.

© 2009-2023 Rocky Mountain Computer Consulting, Inc. All rights reserved.