Why TypeInitialization Exception Has Null Inner Exceptions

This TypeInitializationException occurs when a Type fails to load during Type initialization. Normally, when this exception occurs the InnerException property contains the actual exception details about why the initialization failed. But sometimes it happens to be Null, and so we have questions about it.

Let’s take an example:

  1. class Program  
  2. {  
  3.     static Program()   
  4.   {  
  5.         var initialBootDrive = Directory.Exists("C:\\logs\\BootLogs");  
  6.         if (!initialBootDrive)   
  7.         {  
  8.             throw new IOException("Directory does not exist");  
  9.         }  
  10.     }  
  11.   
  12.     static void Main(string[] args)  
  13.     {  
  14.         Console.WriteLine("Press any key");  
  15.         Console.ReadLine();  
  16.     }  
  17. }  
This will cause the exception to occur. Because the static constructors cannot be called explicitly but will execute when the Type is first accessed. In this case the Type will be accessed for initialization.

The above case isa special case which I want to discuss in this post. The TypeInitialization will occur with null InnnerException.

setting

There is no “View Details” options. Moreover if we click “Copy exception detail to the clipboard” you’ll get this:

System.TypeInitializationException was unhandled Message: An unhandled exception of type
'System.TypeInitializationException' occurred in mscorlib.dll Additional information: The type initializer for 'TypeInitializationExceptionTest.Program' threw an exception.


Not much detail, right? There’s no Inner Exception so you’ll never know what causes this exception to occur.

The reason is that TypeInitializer of Entry method (Main) class has failed. Since no type was initialized at this very moment, the TypeInitializer has no type information to report about the failed type in TypeInitializationException.

As explained more by Jon Skeet, “Once a type initializer has failed once, it is never retried. The type is dead for the lifetime of the AppDomain. (Note that this is true for all type initializers, not just for types with static constructors. A type with static variables with initializer expressions, but no static constructors, can exhibit subtle differences in the timing of the type initializer execution - but it'll still only happen once.”

But if you remove the static constructor from the Entry Type (i.e. Program) to the other class and then refer that class in Entry method, you'll get the InnerException on TypeInitialization exception.
  1. static class BootStrapper   
  2. {  
  3.     public static bool Initializing;  
  4.   
  5.     staticBootStrapper()   
  6.         {  
  7.         varinitialBootDrive = Directory.Exists("C:\\logs\\BootLogs");  
  8.         if (!initialBootDrive)  
  9.         {  
  10.             throw new IOException("Directory does not exist");  
  11.         }  
  12.     }  
  13. }  
  14.   
  15. class Program   
  16. {  
  17.     static void Main(string[] args)   
  18.     {  
  19.         // The first access to the class will cause the static constructor to execute.  
  20.         BootStrapper.Initializing = true;  
  21.   
  22.         Console.WriteLine("Press any key");  
  23.         Console.ReadLine();  
  24.     }  
  25. }  
Now if you run it you’ll get the expected behavior.

code

Final Remark: Keep the Entry (Main) class as clean as possible from the Static member or constructor initialization that throws the exception.

If necessary either avoid throwing the exception, or only throw an exception when those members are being accessed during execution of application.
 
Read more articles on Exceptions in C#: