Can you catch a native exception in C# code?

C#.NetException

C# Problem Overview


In C# code can you catch a native exception thrown from deep in some unmanaged library? If so do you need to do anything differently to catch it or does a standard try...catch get it?

C# Solutions


Solution 1 - C#

You can use Win32Exception and use its NativeErrorCode property to handle it appropriately.

// http://support.microsoft.com/kb/186550
const int ERROR_FILE_NOT_FOUND = 2;
const int ERROR_ACCESS_DENIED = 5;
const int ERROR_NO_APP_ASSOCIATED = 1155; 

void OpenFile(string filePath)
{
	Process process = new Process();

	try
	{
        // Calls native application registered for the file type
        // This may throw native exception
		process.StartInfo.FileName = filePath;
		process.StartInfo.Verb = "Open";
		process.StartInfo.CreateNoWindow = true;
		process.Start();
	}
	catch (Win32Exception e)
	{
		if (e.NativeErrorCode == ERROR_FILE_NOT_FOUND || 
			e.NativeErrorCode == ERROR_ACCESS_DENIED ||
			e.NativeErrorCode == ERROR_NO_APP_ASSOCIATED)
		{
			MessageBox.Show(this, e.Message, "Error", 
					MessageBoxButtons.OK, 
					MessageBoxIcon.Exclamation);
		}
	}
}

Solution 2 - C#

Catch without () will catch non-CLS compliant exceptions including native exceptions.

try
{

}
catch
{

}

See the following FxCop rule for more info http://msdn.microsoft.com/en-gb/bb264489.aspx

Solution 3 - C#

The interop layer between C# and native code will convert the exception into a managed form, allowing it to be caught by your C# code. As of .NET 2.0, catch (Exception) should catch anything other than a nonrecoverable error.

Solution 4 - C#

Somewhere using a .NET Reflector I've seen the following code:

try {
  ...
} catch(Exception e) {
  ...
} catch {
  ...
}

Hmm, C# does not allow to throw an exception not deriving from the System.Exception class. And as far as I known any exception cautch by the interop marshaller is wrapped by the exception class that inherits the System.Exception.

So my question is whether it's possible to catch an exception that is not a System.Exception.

Solution 5 - C#

This depends on what type of native exception you are talking about. If you're referring to an SEH exception then the CLR will do one of two things.

  1. In the case of a known SEH error code it will map it to the appropriate .Net exception (i.e. OutOfMemoryException)
  2. In the case of an un-mappable (E_FAIL) or unknown code it will just throw an http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.sehexception.aspx">SEHException</a> instance.

Both of these will be caught with a simple "catch (Exception)" block.

The other type of native exception which can cross the native/managed boundary are C++ exceptions. I'm not sure how they are mapped/handled. My guess is that since Windows implements C++ exceptions on top of SEH, they are just mapped the same way.

Solution 6 - C#

Almost, but not quite. You will catch the exception with

try 
{
  ...
}
catch (Exception e)
{
  ...
}

but you will still have potential problems. According to MSDN, in order to insure exception destructors are called you would have to catch like:

try
{
  ...
}
catch
{
  ...
}

This is the only way to insure an exception destructor is called (though I'm not sure why). But that leaves you with the tradeoff of brute force versus a possible memory leak.

Incidentally, if you use the (Exception e) approach you should know the different types of exceptions you might come across. RuntimeWrappedException is what any managed non-exception type will be mapped to (for languages that can throw a string), and others will be mapped, such as OutOfMemoryException and AccessViolationException. COM Interop HRESULTS or exceptions other than E___FAIL will map to COMException, and finally at the end you have SEHException for E_FAIL or any other unmapped exception.

So what should you do? Best choice is don't throw exceptions from your unamanaged code! Hah. Really though if you have a choice, put up barriers and failing that make the choice of which is worse, a chance of a memory leak during exception handling, or not knowing what type your exception is.

Solution 7 - C#

With .Net Framework 4.8 IF the exception is handled nicely within the native code then you can catch it with a standard try catch.

try 
{
   //call native code method
} 
catch (Exception ex) 
{
   //do stuff
} 

HOWEVER, if the native code is in a 3rd party dll you have no control over, you may find that the developers are inadvertently throwing unhandled exceptions. I have found NOTHING will catch these, except a global error handler.

private static void Main()
{
    AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
    try 
    {
       //call native code method
    } 
    catch (Exception ex) 
    {
       //unhandled exception from native code WILL NOT BE CAUGHT HERE
    } 
}

private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    var exception = e.ExceptionObject as Exception;
    //do stuff
}

There is a reason for this. Unhandled native exceptions can indicate a corrupted state that you can't recover from (eg stack overflow or access violation). However, there are cases you still want to do stuff before terminating the process, like log the error that just tried to crash your windows service!!!

A bit of History

None of the following is required any more.
From .Net 2.0 - 3.5 you could use an empty catch:

try 
{
   //call native code method
} 
catch (Exception ex) 
{
   //do stuff
} 
catch 
{
   //do same stuff but without any exception detail
}

From .Net 4 they turned off native exceptions being abled to be caught by default and you needed to explicitly turn it back on by decorating your methods with attributes.

[HandleProcessCorruptedStateExceptions] 
[SecurityCritical]
private static void Main() 
{ 
    try 
    {
       //call native code method
    } 
    catch (Exception ex) 
    {
       //do stuff
    } 
}

also required was a change to the app.config file:

<configuration>  
   <runtime>  
      <legacyCorruptedStateExceptionsPolicy enabled="true" />  
   </runtime>  
</configuration>  

Solution 8 - C#

A standard try catch should do the trick i believe.

I run into a similar problem with a System.data exception throwing a sqlClient exception which was uncaught, adding a try..catch into my code did the trick in the instance

Solution 9 - C#

If you use a

try
{

}
catch(Exception ex)
{

}

it will catch ALL exceptions, depending on how you call the external libraries you might get a com related exception that encapsulates the error but it will catch the error.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - C#VivekView Answer on Stackoverflow
Solution 2 - C#trampsterView Answer on Stackoverflow
Solution 3 - C#Curt HagenlocherView Answer on Stackoverflow
Solution 4 - C#Michael DamatovView Answer on Stackoverflow
Solution 5 - C#JaredParView Answer on Stackoverflow
Solution 6 - C#nedruodView Answer on Stackoverflow
Solution 7 - C#JumpingJezzaView Answer on Stackoverflow
Solution 8 - C#DeanView Answer on Stackoverflow
Solution 9 - C#Mitchel SellersView Answer on Stackoverflow