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?
9 Answers
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);
}
}
}

- 16,360
- 5
- 30
- 37
-
7I believe this isn't automatic, but only thrown when you use a P/Invoke signature that specifies it. And it's thrown based on a Win32 error code, not a Win32 exception. – Curt Hagenlocher Sep 29 '08 at 22:56
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

- 8,598
- 4
- 37
- 52
-
14Yep this is true. Just discovered this myself after a particularly annoying few hours spent comparing log files and code and thinking I was loosing it. The obvious follow on question though, is can you determine the type of native exception from within the empty catch block? Can you log anything useful to identify the source of the exception? – Tyson Dec 06 '12 at 10:38
-
10 years later... This doesn't seem to be needed anymore, so I think catch(ex) is OK now. The FxCop link above says the rule is now deprecated, and the corresponding issue on roslyn-analyzers github (https://github.com/dotnet/roslyn-analyzers/issues/481) says "Not relevant any more because the CLR wraps non-Exception-derived throws" – Kevin Holt Oct 26 '21 at 17:26
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.

- 20,680
- 8
- 60
- 50
-
3In .NET 1.x, it's possible for an exception to be thrown that doesn't derive from the Exception class, but this ability is turned off by default in 2.0 – Curt Hagenlocher Sep 29 '08 at 20:44
-
4In C++ you can throw any object, so for interop issues it's useful to be able to catch an object which doesn't derive from Exception. A common scenario is that C++ program will throw a String only (the error message). – MattDavey Sep 09 '11 at 13:08
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.

- 15,253
- 10
- 46
- 71
-
1It is possible to emit or otherwise create IL that throws an arbitrary object. The C# compiler won't let you do it, but other compilers may, or like I said you can directly emit the IL. A catch statement with no type will catch arbitrary objects as well as objects inheriting Exception. – technophile Sep 29 '08 at 20:55
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.
- In the case of a known SEH error code it will map it to the appropriate .Net exception (i.e. OutOfMemoryException)
- In the case of an un-mappable (E_FAIL) or unknown code it will just throw an SEHException 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.
-
*`Windows implements C++ exceptions on top of SEH`* -- this seems to be true only for VC? – Wolf Jan 10 '17 at 14:27
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>

- 5,498
- 11
- 67
- 106
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.

- 1,122
- 2
- 9
- 19
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

- 5,896
- 12
- 58
- 95
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.

- 62,228
- 14
- 110
- 173
-
You can't catch a StackOverflow or OutOfMemoryException though, no matter what, correct? – core Sep 30 '08 at 05:14
-
those are ending errors, that halt the application, so yes you cannot work with them. – Mitchel Sellers Sep 30 '08 at 13:58
-
7This isn't actually quite correct, this will catch all CLS compliant exceptions. C++/CLI and MC++ are both languages capable of throwing non CLS Compliant exceptions. – Peter Oehlert Mar 25 '11 at 16:47
-
1I agree with Peter, I'm working with unmanaged DLLs and i can't catch some exceptions. – Tilendor Jun 09 '11 at 20:49
-
20This question has 17 upvotes and 7 faves as of when I am writing this comment, so this is clearly an issue that is happening to people and I'd think people would try a simple catch block before resorting to SO. I have personally seen exceptions explode right through the construct you propose when they come from unmanaged dependencies. I don't think this answer is correct. – JohnFx Jun 22 '11 at 13:56
-
@PeterOehlert sure, this has issues that it only catches subcalsses of the `Exception` class, but you can catch the rest using `catch(...){}`, no? – will Apr 26 '17 at 08:34
-
I tried this and it does not catch all exceptions. For example, I was getting ucrtbase.dll error 0xc0000409 and it wasn't caught by System.Exception – Brian Colavito Feb 14 '18 at 16:44