#867 – Including Several catch Blocks

You can include several catch blocks in a single try-catch statement, each catch block set up to catch a different kind of exception.

            try
            {
                DoSomething(5);
            }
            catch (FileNotFoundException noFileExc)
            {
                Console.WriteLine(string.Format("File Not Found: {0}", noFileExc.FileName));
            }
            catch (ArgumentOutOfRangeException argExc)
            {
                Console.WriteLine("Your arguments were not within valid ranges");
            }
            catch (Exception exc)
            {
                Console.WriteLine("Crap!");
                Console.WriteLine(exc.Message);
            }

If an exception originates within the the scope of the try block and if the exception is not caught at a lower level, it will bubble up to the code containing this try-catch statement.  The type of the exception object will then be compared to the exception types specified in the catch blocks, starting with the first block.  If a matching type is found, the code in that catch block will execute and the exception will not propagate further up the call stack.

#866 – A catch Block Without Arguments Catches All Exceptions

You typically include an argument in a catch block that indicates the type of exception to catch.

            catch (FileNotFoundException fnfExc)
            {
                Console.WriteLine(string.Format("Hey, we can't find file {0}!",
                                                fnfExc.FileName));
            }

You can also omit the arguments on the catch block entirely.  In this case, the catch block will catch all exceptions, regardless of their type.  Because you don’t declare an exception variable, however, you won’t have access to information about the exception.

            try
            {
                DoSomething();
            }
            catch
            {
                Console.WriteLine("No idea of what happened, but it must be something bad");
            }

Although possible, not specifying the type of exception to catch is not recommended.  Even exceptions originating from outside of CLS-compliant code will be wrapped in an exception whose type derives from Exception.  So you should always specify an exception variable in the catch clause.

#864 – An Example of a finally Block with No catch Block

When an exception occurs while executing code in a try block that has an associated finally block, the code in the finally block will execute before the exception bubbles up the call stack.

Below is an example.  MethodA calls MethodB, which in turn calls MethodC.  MethodC throws an exception.  When this happens, the code in MethodB’s try block is interrupted and the code in the finally block is executed.  The exception then bubbles up the call stack, where it is then caught by the catch block in MethodA.

        private static void MethodA()
        {
            try
            {
                MethodB();
                Console.WriteLine("After MethodB call");
            }
            catch (Exception xx)
            {
                Console.WriteLine("Exception caught in MethodA!");
            }

            Console.WriteLine("Finishing up MethodA");
        }

        private static void MethodB()
        {
            try
            {
                Console.WriteLine("Before MethodC() call");
                MethodC();
                Console.WriteLine("After MethodC() call");
            }
            finally
            {
                Console.WriteLine("MethodB() finally block");
            }

            Console.WriteLine("Finishing up MethodB()");
        }

        private static void MethodC()
        {
            throw new Exception("Uh-oh");
        }

864-001

#863 – How a finally Block Works with No catch Block

When you include a finally block with some code that’s surrounded by a try block, you’re saying that you want the code in the finally block to run after the code in the try block, whether or not an exception occurs.

If no exception occurs while executing the statements in the try block, the statements in the finally block simply execute after the code in the try block.

If an exception does occur and you have a finally block, but no catch block, the following happens:

  • Some of the code in the try block executes, up to the point where the exception occurred
  • The code in the finally block executes
  • The exception continues bubbling up the call stack
  • Code in the current method that’s located after the finally block does not execute

#862 – Options for Including catch and finally Blocks

When you define a try block using the try keyword, you must also do one of the following:

  • Include one or more catch blocks after the try block
  • Include a finally block after the try block
  • Include one or more catch blocks after the try block, followed by a finally block

Whether you include a catch block, a finally block, or both, depends on what you want to accomplish:

  • Include catch blocks to intercept and act upon exceptions that got thrown as a result of executing the code in the try block.
  • Include a finally block if there are things that need to happen (like releasing resources), regardless of whether or not an exception occurs.
  • Include both catch and finally blocks if both statements above are true.

#861 – A finally Block Always Executes

When you use a try block, you’re defining a block of code for which you can catch an exception, using a catch block.  You can also include a finally block, which dictates a block of code that will execute whether or not an exception occurs.

Suppose that you have the following code:

                try
                {
                    Console.WriteLine("BEFORE the call");
                    SomeMethod();
                    Console.WriteLine("AFTER the call");
                }
                catch (Exception exc)
                {
                    Console.WriteLine("Exception caught in catch block");
                }
                finally
                {
                    Console.WriteLine("Code in finally block executing");
                }

If an exception does not occur, all of the code in the try block will execute, followed by all of the code in the finally block.

861-001

 

If the SomeMethod method throws an exception, the code in the try block after the call to SomeMethod will not execute.  Instead, the code in the catch block will execute, followed by the code in the finally block.

861-002

#860 – Exceptions Bubble up the Call Stack

When you define a try/catch block, the handler defined in the catch block will catch exceptions that originate directly from the code in the try block.  But the handler will also catch exceptions that originate in methods called from the code in the try block, or from code that those methods call.  In short, a catch block will catch any exceptions thrown by code that executes as a result of executing the block of code in the try block.  (Assuming that the exception is not caught elsewhere).

In the example below, code within a try block calls SomeMethod, which calls AnotherMethod.  AnotherMethod then calls YetAnother.  If an exception is thrown from the YetAnother method, the exception will bubble up the call stack until an exception handler is found.  In this the handler associated with the try block around the SomeMethod call will catch the exception.

860-001