#1,219 – C# 6.0 – Filtering Exceptions

C# 6.0 will include support for exception filters, that is–only catching a particular type of exception if an associated expression evaluates to true.

You can filter exceptions by including an if statement after the catch expression.  If the result of evaluating the expression supplied is true, the exception is caught.  If not, the behavior is as if you didn’t supply a catch block.

In the example below, we don’t catch divide by zero exceptions on Saturdays.

            int denom;
            try
            {
                denom = 0;
                int x = 5 / denom;
            }
            // Catch /0 on all days but Saturday
            catch (DivideByZeroException xx) if (DateTime.Now.DayOfWeek != DayOfWeek.Saturday)
            {
                Console.WriteLine(xx);
            }

#1,192 – Following the TryParse Pattern

The int.TryParse method does the same thing as the int.Parse method, but without throwing an exception.  Instead, it returns a boolean value indicating whether the method succeeded or not and writes the result to an out parameter.

You might follow the same pattern when writing your own code, providing a method that throws an exception on failure and a TryXxx version of the method that returns a boolean indicating whether the method succeeded.  Below is an example.

    public class Dog
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public bool TryBark(out string barkSound)
        {
            bool success = false;
            barkSound = "";

            if (Age <= 10)
            {
                success = true;
                barkSound = "Woof";
            }

            return success;
        }

        public string Bark()
        {
            string barkSound;

            if (!TryBark(out barkSound))
                throw new Exception("This dog can't bark");
            return barkSound;
        }
    }

#920 – A finally Block Is Not Executed When a Corrupted State Exception Occurs

When a corrupted state exception occurs as a result of executing some code within a try block, code within an associated finally block is not executed.  This is true whether or not you use the HandleProcessCorruptedStateExceptions attribute to indicate that you want to catch corrupted state exceptions.

In the example below, we execute some code that causes an access violation and a corrupted state exception occurs.  We do catch the CSE, but the code within our finally block is never executed.

        [HandleProcessCorruptedStateExceptions]
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Before call to CausesAccessViolation()");
                CausesAccessViolation();
                Console.WriteLine("Before call to CausesAccessViolation()");
            }
            catch (Exception exc)
            {
                Console.WriteLine(string.Format("Hey, I caught an Exception: {0}", exc.ToString()));
            }

            Console.ReadLine();
        }

        static void CausesAccessViolation()
        {
            try
            {
                IntPtr ptr = new IntPtr(123);
                Marshal.StructureToPtr(123, ptr, true);
            }
            finally
            {
                Console.WriteLine("* finally block in CausesAccessViolation() executing");
            }
        }

920-001

#919 – Think Twice about Handling Corrupted State Exceptions

Corrupted State Exceptions are exceptions that indicate that the memory state of the current process is likely corrupt.  These CSEs by default cannot be caught by your code.  This is normally what you want, since you typically don’t want to continue execution when one of these exceptions occurs.  You can, however, use the HandleProcessCorruptedStateExceptions attribute to indicate that you do want to handle CSEs.

Be very careful when handling Corrupted State Exceptions.  When an exception in this category is thrown, there is a good chance that the memory space of your process is corrupt.  Continuing execution may lead to unpredictable behavior and could even cause other data to become corrupt.

If you do catch Corrupted State Exceptions, you should execute as little code as possible and exit your application as soon as possible.  You might, for example, just log the fact that the CSE occurred and then exit.

#918 – Catching Corrupted State Exceptions

Corrupted State Exceptions are exceptions that indicate that the memory state of the current process is likely corrupt.  These CSEs by default cannot be caught by your code.  This is normally what you want, since you typically don’t want to continue execution when one of these exceptions occurs.

You can, however, set an attribute on a method indicating that you do want to catch Corrupted State Exceptions.  If you set the HandleProcessCorruptedStateExceptions attribute on a method, it will then be able to catch this category of exceptions.

In the example below, we are able to catch the access violation exception.

        [HandleProcessCorruptedStateExceptions]
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Before call to CausesAccessViolation()");
                CausesAccessViolation();
                Console.WriteLine("Before call to CausesAccessViolation()");
            }
            catch (Exception exc)
            {
                Console.WriteLine(string.Format("Hey, I caught an Exception: {0}", exc.ToString()));
            }

            Console.ReadLine();
        }

        static void CausesAccessViolation()
        {
            IntPtr ptr = new IntPtr(123);
            Marshal.StructureToPtr(123, ptr, true);
        }

918-001

#917 – Corrupted State Exceptions Are Not Normally Caught

Starting with .NET 4.0, there are a class of exceptions that will not be caught within a general catch block that catches all exceptions deriving from System.Exception.  By default, a corrupted state exception will not be caught as a System.Exception.  A corrupted state exception is a type of exception, like an access violation, that likely results in the internal state of the process being corrupt.

In the example below, we artificially generate an access violation.  Note that the exception that is raised is not caught, but treated as an unhandled exception.  (Our catch block never executes).

        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Before call to CausesAccessViolation()");
                CausesAccessViolation();
                Console.WriteLine("Before call to CausesAccessViolation()");
            }
            catch (Exception exc)
            {
                Console.WriteLine(string.Format("Hey, I caught an Exception: {0}", exc.ToString()));
            }

            Console.ReadLine();
        }

        static void CausesAccessViolation()
        {
            IntPtr ptr = new IntPtr(123);
            Marshal.StructureToPtr(123, ptr, true);
        }

917-001

#916 – Exception Can Cross .NET Language Boundaries

An exception being thrown from one assembly can be caught in a different assembly.  This is true even when the assemblies are authored in different .NET languages.

Below, code in the ConsoleApplication2 assembly, which is written in Visual Basic, calls code in the DogLibrary assembly (the Dog.Bark method), which is written in C#.  When an exception originates in DogLibrarywe can catch it in the code running in ConsoleApplication2.

916-001

Assume that the code in DogLibrary looks like:

        public void Bark(int numTimes)
        {
            if (numTimes > 10)
                throw new ApplicationException("Too many times to bark");

            for (int i = 0; i < numTimes; i++)
                Console.WriteLine("Woof");
        }

And the code in ConsoleApplication2 looks like:

    Sub Main()
        Try
            Dim d As Dog = New Dog("Bowser")
            d.Bark(100)

        Catch ex As Exception
            Console.WriteLine(String.Format("Uh-oh! {0}", ex.ToString()))
        End Try
    End Sub

We can catch the exception in the VB code that was thrown by the C# code.
916-002