Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a generic exception supported inside a catch?

The above block refering to another question+answer on SO does NOT contain a correct answer which applies here!

I have a method used for unit testing. The purpose of this method is to ensure that a piece of code (refered to by a delegate) will throw a specific exception. If that exception is thrown, the unit test succeeds. If no exception is thrown or another type exception is thrown, the unit test will fail.

/// <summary>
/// Checks to make sure that the action throws a exception of type TException.
/// </summary>
/// <typeparam name="TException">The type of exception expected.</typeparam>
/// <param name="action">The code to execute which is expected to generate the exception.</param>
public static void Throws<TException>(Action action) 
    where TException : Exception
{
    try
    {
        action();
    }
    catch (TException)
    {
        return;
    }
    catch (Exception ex)
    {
        Assert.Fail("Wrong exception was thrown. Exception of type " + ex.GetType() + " was thrown, exception of type " + typeof(TException) + " was expected.");
    }
    Assert.Fail("No exception was thrown. Exception of type " + typeof(TException) + " was expected.");
}

The next call should succeed, but it fails:

int result = 0;
Throws<DivideByZeroException>(() => result = result / result);

When the expected exception of type TException is thrown, it is always caught by the second catch, not by the first catch. Why is this?

Of course I can use a workarround with one catch and test if ex is of type TException. By I simply want to know/understand why this code compiles but simple (never?) works.

EDIT

At request a "working" demo:

using System;

namespace GenericExceptionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 0;
            Catch<DivideByZeroException>(() => n = n / n);
        }

        static public void Catch<TException>(Action action)
            where TException: Exception
        {
            try
            {
                action();
                Console.WriteLine("No exception thrown. !!!Fail!!!");
            }
            catch (TException)
            {
                Console.WriteLine("Expected exception thrown. PASS!");
            }
            catch(Exception ex)
            {
                Console.WriteLine("An unexpected exception of type " + ex.GetType() + " thrown. !!!FAIL!!!");
            }
        }
    }
}
like image 927
Martin Mulder Avatar asked Jun 05 '13 10:06

Martin Mulder


People also ask

Is it OK to catch generic exception?

Don't catch generic Exceptions While this seems harmless, some unintended side effects could result. For example, if className() is null, Class. forName() will throw a NullPointerException , which will be caught in the method.

How do you handle generic exceptions?

The generic exception handler can handle all the exceptions but you should place is at the end, if you place it at the before all the catch blocks then it will display the generic message. You always want to give the user a meaningful message for each type of exception rather then a generic message.

What are generic exceptions in Java?

It refers to exception class that is near the top of the exception class hierarchy. Note that an exception class cannot be a generic class ... in the Java sense of generic types. The JLS says: "Note that a subclass of Throwable cannot be generic (§8.1.2)." -


1 Answers

You're not the first person to encounter this problem. This question is very similar. If you dig through the answers and links, it comes down to a bug in the CLR.

EDIT: As a follow up, I've run Martin's example from VS2010 and got the following results:

  • Targetting .NET 4, PASS
  • Targetting .NET 3.5, FAIL
  • Targetting .NET 3.5 in RELEASE mode, PASS

Sadly, all the SO links to the Microsoft Bug Report are dead now and I haven't been able to find any others.

like image 157
Chris Spicer Avatar answered Oct 19 '22 03:10

Chris Spicer