38

See below for an explanation of what is going on

I have a really weird issue where the exception caught is null.

The code uses MEF and tries hard to report composition errors. Using the debugger I can see the exception being thrown (an InvalidOperationException) but when it is caught by the last catch block in the code below the ex variable is null. This is true both in the debugger and when executing the code normally.

static T ResolveWithErrorHandling<T>() where T : class
{
    try
    {
        IocContainer.Compose(Settings.Default.IocConfiguration);
        return IocContainer.Resolve<T>();
    }
    catch (ReflectionTypeLoadException ex)
    {
        // ... special error reporting for ReflectionTypeLoadException
    }
    catch (Exception ex)
    {
        // ex is null - that should not be possible!
        // ... general error reporting for other exception types
    }
    return null;
}

The code I have replaced with comments is really simple code to format the error message. Nothing strange going on there.

I have tried to alter the code to discover what effect that might have:

  • If I remove the first catch block (ReflectionTypeLoadException) the exception caught in the final catch block is no longer null.
  • If I catch another exception type in the first catch block the exception caught in the final catch block is no longer null.
  • If I add a catch block for InvalidOperationException as the first catch block the exception caught in that block is not null.
  • If I add a catch block for InvalidOperationException between the two catch blocks the exception caught in that block is null.

The project uses Code Contracts and the code generated by the compiler is post-processed to check the contracts. Unfortunately, I havn't figured out a way to get rid of this for testing purposes without performing major surgery on the project.

My current workaround is to not catch ReflectionTypeLoadException and instead branch on the type of ex in the general exception handler.

What could be the explanation for this "impossible" behavior? What is up with ReflectionTypeLoadException catch block?


Embarrassingly the exception is not null and it cannot be null per the C# standard 15.9.5.

However, using Code Contracts in a project can mess up the display of local variables in the debugger because the IL code generated by the compiler can be rewritten by Code Contracts so the final IL is slightly out of sync with the debug information. In my case the ex variable is displayed as null even it is not. The unfortunate nature of the error reporting taking place right before application termination meant that I believed the error reporting to not be called as a result of ex being null and ex.Message throwing a NullReferenceException inside my catch block. Using the debugger I was able to "verify" that ex was null, except it was actually not null.

My confusion was compounded by the fact that a catch block for ReflectionTypeLoadException seems to affect the debugger display issue.

Thanks to all who responded.

Community
  • 1
  • 1
Martin Liversage
  • 96,855
  • 20
  • 193
  • 238
  • Is there actually a `ReflectionTypeLoadException` being thrown anywhere? – Jaymz Apr 13 '11 at 14:30
  • 1
    Just a note, but can you handle the different types of exception or are you just reporting the same for each? If this is generic reporting and you can't _handle_ the exception then I'm not sure you'll need to scope the catches anyway. – Grant Thomas Apr 13 '11 at 14:35
  • What happens when you add a catch for InvalidOperationExecption? – Emond Erno Apr 13 '11 at 14:37
  • @Jaymz: Yes, if an assembly included in the composition cannot be loaded. The exception carries some extra information that can assist in troubleshooting the problem, and that information is extracted in the catch block. – Martin Liversage Apr 13 '11 at 14:38
  • It looks as if the `catch (ReflectionTypeLoadException ex)` line eats the exception... – Emond Erno Apr 13 '11 at 14:45
  • hmmm, can an exception not inherit Exception – Jodrell Apr 13 '11 at 14:46
  • @Mr. Disappointment: I appreciate your general advice on exception handling, but what I really would like to know is the cause for the null exception. In this particular case the catch blocks are perfectly sane as they are used to improve the error reporting. The exception handler is a top-level handler and if null is returned by the method (an exception is thrown) the application is unable to continue and terminates. – Martin Liversage Apr 13 '11 at 14:48
  • @Martin: Appreciated. I didn't mean to question the sanity of the code, just trying to save yours a little if possible and in case clients are involved (yikes!) - ultimately you do need to know _why_ this is happening, I wholeheartedly agree. – Grant Thomas Apr 13 '11 at 14:53
  • I can't believe it, but giving the "ex" variables different names worked for me. VS2013 Update 4. – Ben Cull Jan 12 '15 at 13:14

6 Answers6

13

Just ran into this same problem. I finally found out that I catched different exceptions with the same name, like you did:

catch (ReflectionTypeLoadException ex)
{
    // ... 
}
catch (Exception ex)
{
    // ex is not null!
    // ...
}

Both are named 'ex'. Changing one of both names solved this problem for me, like:

catch (ReflectionTypeLoadException reflectionEx)
{
    // ... 
}
catch (Exception ex)
{
    // ex is null - that should not be possible!
    // ...
}
Guido Kersten
  • 176
  • 1
  • 5
5

I ran in the same problem. In my case renaming the exception variable (e.g. ex => ex1) allowed to me to catch any exception...

AMa
  • 51
  • 1
  • 1
4

I ran into the same problem. The exception was null when viewed in the debugger even though the correct type of exception - UpdateException - was being caught. I could view the exception by opening the Exception Assistant.

As soon as I turned off "Perform Runtime Contract Checking" caught exceptions where no longer null. I have been actively using code contracts for going on a year now and had not seen this problem before I starting working with EF 4.1 in this particular project recently - but I do not know if EF was a controlling variable in regards to caught exceptions being null.

4

You should check if at some point, the IocContainer catches an Exception ex throws ex.InnerException without checking if it is null.

C# happily accepts throw null, and ends up in catch (Exception).

C.Evenhuis
  • 24,516
  • 2
  • 54
  • 68
  • 4
    If you throw a null exception (e.g. if `ex.InnerException` is null) you instead get a `NullReferenceException` thrown. In C# the exception caught can never be null. Except it is in my case ... – Martin Liversage Apr 13 '11 at 14:56
  • Ahh, my bad, I just had a hunch, set up a test case, hovered over the `ex` variable and saw "reference not set to an instance", mistaked it for a real null. – C.Evenhuis Apr 13 '11 at 21:24
1

The exception is in fact not null, it's a problem with the debugger. Code contracts (ccrewrite) changes IL opcodes and that perturbates the debugger, because leave.s opcodes are transformed into leave opcodes. The two opcodes have different sizes and instruction adresses change, that's why the debugger is lost when exception names are the same.

You can use $exception in the debugger to workaround the issue.

dou bret
  • 255
  • 2
  • 11
0

I have got the same situation, too. It happened to be a bug of Eclipse debugger. (Really, this situation can be only the result of some debugger's bug. )

Eclipse restart was enough - runtime exception becomes normal, not null. Other debuggers could be not so kind.

Gangnus
  • 22,127
  • 14
  • 79
  • 132