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?
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);
}
}
}
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
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.
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.
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.
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>
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.
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
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.
Related
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?
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);
}
}
}
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
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.
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.
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.
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>
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.
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
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.
Apologies for the lack of information...
Is there a way to find out what is the specific Exception that is causing a call to throw the Exception?
Currently, I am catching all the Exceptions by doing catch(Exception e) but I know this is not good practices at all.
Is there a way to know from the Exception what is the specific one that caused the issue so I can be more granular?
You can get more information for the particular exception using different methods on it. Here I'm using the System.Diagnostics.Debug class to print in Visual Studio's output console. In your catch block:
using System.Diagnostics;
try
{
// do stuff
}
catch (Exception e)
{
Debug.WriteLine(e.GetType()); // Displays the type of exception
Debug.WriteLine(e.Message()); // Displays the exception message
}
You can see more here: Exception methods &
Exception properties
Option 1 - Documentation
Read the documentation of the method you are calling, if it is a Framework Class type (like SqlConnection.Open) the thrown exceptions are well documented.
Option 2 - Discover them at Run Time
If its a 3rd party library and documentation is limited then check the Exception at runtime using exception.GetType() and then add known exceptions you want to handle as catch blocks.
Personally I prefer to not add catch blocks at all where I am not sure if an Exception will materialize or not. If/When it does the debugger will break (if it is set to break) or you have a global catch all that logs and rethrows. Then you get the type and update your code accordingly. Where you add such a global Exception logger depends on the type of application you are developing. If you go the route of a global logger do take note that you 1) rethrow the Exception so the app breaks at runtime and not swallow it and 2) rethrow using throw; syntax (not throw ex;).
You can catch different types of exceptions. With this solution you are able to handle the different types easily.
try
{
//Try something
}
catch (StackOverflowException soe)
{
//Handle StackOverFlowException
}
catch (FormatException fe)
{
//Handle FormatException
}
//... Other exceptions
If you want to make it more specific for logging errors, try something like:
e.GetType()
Or, if you need some more information like the StackTrace or message:
e.ToString()
If you only want to catch a specific type of exception, you need to do something like:
try {
// someCode
} catch (SpecificExceptionType e) {
// someCode (e.g. Console.WriteLine(e.ToString()); )
}
catch (AnotherSpecificExceptionType e) {
// someCode (e.g. Console.WriteLine(e.ToString()); )
}
I have a webservice that returns xml.The problem is methods that are executed "deep" in code where a simple return won't stop program execution.
What happens is I set my xml error message in a catch statement but the code will keep executing through the rest of the outer method and overwrite my xml error response.
Is there a design pattern or best practice to get around this?
Main Program Block SomeClass
execute someMethod() ----> public someMethod()
{
-----> private method()// try / catch error occurred (send back an xml error response)
// code execution continues and does some stuff and generates an xml response
<request>
<success>true</success>
</request>
}
catch (Exception)
{
// Set errors here
throw;
}
This will rethrow the exception. Is that what you're looking for?
You can re-throw the exception. For example:
private static string errorMessage;
static void Main(string[] args)
{
try
{
Test1();
}
catch (Exception ex)
{
Console.WriteLine("Something went wrong deep in the bowels of this application! " + errorMessage );
}
}
static void Test1()
{
try
{
Test2(1);
Test2(0);
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw;
}
}
static string Test2(int x)
{
if (x==0) throw new ArgumentException("X is 0!");
return x.ToString();
}
An additional piece of advice: When re-throwing an exception, use throw;, not throw ex;, in order to preserve the stack trace. See this for some more information on the subject.
You need to consider setting up Exception boundaries within your architecture.
I've used Microsoft's Exception Handling Block successfully in the past to do this.
This will allow you to set up different policies for dealing with and propagating exceptions as shown in the diagram below;
It will help you deal with scenarios such as;
Logging
Replacing
Wrapping
Propagating
User friendly messages
It's worth a look depending on how far you want to take your exception handling.
It's generally wise to catch your exceptions as far up the chain as possible. So it would be the main service method's responsibility to catch different types of exceptions and determine the appropriate response. Deep-down code should not just "swallow" the exception unless it really knows how to handle it and move on gracefully.
If you want to make it so certain exceptions can tell the upper-level code that it's supposed to use specific information for the response, you can create a custom exception type with properties that the exception-catching code in the service method can check.
// In your deep down code
catch (Exception e)
{
throw new ReturnErrorMessageException("The user should see this message.", e);
}
// In your service method
catch (SendErrorMessageException e)
{
Response.Message = e.UserFacingErrorMessage;
_logger.LogError("An error occurred in the web service...", e);
}
Probably the best solution for what you are looking for is to use Aspect Oriented Programming (AOP) and create an Exception handling Aspect(s) that catches and handles all the exceptions then you check for exceptions at the service level.
The advantage of this is it removes the try catch from your code and enables you to handle the exceptions in the a modular manner.
Some AOP solutions for .NET include Castle Windsor, Spring.NET and Microsoft Unity.
I have created a WCF service and client and it all works until it comes to catching errors. Specifically I am trying to catch the EndpointNotFoundException for when the server happens not to be there for whatever reason. I have tried a simple try/catch block to catch the specific error and the communication exception it derives from, and I've tried catching just Exception. None of these succeed in catching the exception, however I do get
A first chance exception of type
'System.ServiceModel.EndpointNotFoundException'
occurred in System.ServiceModel.dll
in the output window when the client tries to open the service. Any ideas as to what I'm doing wrong?
I was able to replicate your issue and got interested (since I needed the same). I even researched a way to handle \ catch first chance exceptions but unfortunately it is not possible (for managed code) for .net framework 3.5 and below.
On my case I always get a System.ServiceModel.CommunicationObjectFaultedException whenever something gets wrong on the service or whenever I access a down service. It turns out that c#'s using statement is the cause since behind the scene, the using statement always closes the service client instance even if an exception was already encountered (it doesn't jump to catch statement directly).
What happens is that the original exception System.ServiceModel.EndpointNotFoundException will be replaced by the new exception System.ServiceModel.CommunicationObjectFaultedException whenever the using tries to close the service client instance.
The solution i've made is to not use the using statement so that whenever an exception is encountered inside the try block it will instantly throw the exception to the catch blocks.
Try to code something like:
DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient();
try
{
svc.GetChart(0);
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here
}
catch (Exception ex)
{
//general exception handler
}
finally
{
if (!svc.State.Equals(System.ServiceModel.CommunicationState.Faulted) && svc.State.Equals(System.ServiceModel.CommunicationState.Opened))
svc.Close();
}
Instead of:
try
{
using (DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient())
{
svc.GetChart(0);
}
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here (I was never able to catch this type of exception using the using statement block)
}
catch (Exception ex)
{
//general exception handler
}
And you'll be able to catch the right exception then.
Take a look at this post for details on this possible solution. The code shows use of a generate proxy but is valid on ChannelFactory and others as well.
Typical here-be-dragons pattern
using (WCFServiceClient c = new WCFServiceClient())
{
try
{
c.HelloWorld();
}
catch (Exception ex)
{
// You don't know it yet but your mellow has just been harshed.
// If you handle this exception and fall through you will still be cheerfully greeted with
// an unhandled CommunicationObjectFaultedException when 'using' tries to .Close() the client.
// If you throw or re-throw from here you will never see that exception, it is gone forever.
// buh bye.
// All you will get is an unhandled CommunicationObjectFaultedException
}
} // <-- here is where the CommunicationObjectFaultedException is thrown
Proper pattern:
using (WCFServiceClient client = new WCFServiceClient())
{
try
{
client.ThrowException();
}
catch (Exception ex)
{
// acknowledge the Faulted state and allow transition to Closed
client.Abort();
// handle the exception or rethrow, makes no nevermind to me, my
// yob is done ;-D
}
}
Or, as expressed in your question without a using statement,
WCFServiceClient c = new WCFServiceClient();
try
{
c.HelloWorld();
}
catch
{
// acknowledge the Faulted state and allow transition to Closed
c.Abort();
// handle or throw
throw;
}
finally
{
c.Close();
}
This may be a reporting issue for the debugger, rather than not actually catching the exception. this post gives some tips on resolving it, if that is the case... Why is .NET exception not caught by try/catch block?
What is a First Chance Exception?
First chance exception messages most
often do not mean there is a problem
in the code. For applications /
components which handle exceptions
gracefully, first chance exception
messages let the developer know that
an exceptional situation was
encountered and was handled.
Place a try catch block in the CompletedMethod.
An Example:
...
geocodeService.ReverseGeocodeCompleted += ReverseGeocodeCompleted(se, ev);
geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);
}
private void ReverseGeocodeCompleted(object sender, ReverseGeocodeCompletedEventArgs e)
{
try
{
// something went wrong ...
var address = e.Result.Results[0].Address;
}
catch (Exception)
{ // Catch Exception
Debug.WriteLine("NO INTERNET CONNECTION");
}
Suppose I have the following two classes in two different assemblies:
//in assembly A
public class TypeA {
// Constructor omitted
public void MethodA
{
try {
//do something
}
catch {
throw;
}
}
}
//in assembly B
public class TypeB {
public void MethodB
{
try {
TypeA a = new TypeA();
a.MethodA();
}
catch (Exception e)
//Handle exception
}
}
}
In this case, the try-catch in MethodA just elevates the exception but doesn't really handle it. Is there any advantage in using try-catch at all in MethodA? In other words, is there a difference between this kind of try-catch block and not using one at all?
In your example, there is no advantage to this. But there are cases where it is desirable to just bubble up a specific exception.
public void Foo()
{
try
{
// Some service adapter code
// A call to the service
}
catch (ServiceBoundaryException)
{
throw;
}
catch (Exception ex)
{
throw new AdapterBoundaryException("some message", ex);
}
}
This allows you to easily identify which boundary an exception occurred in. In this case, you would need to ensure your boundary exceptions are only thrown for code specific to the boundary.
Yes there is a difference. When you catch an exception, .NET assumes you are going to handle it in some way, the stack is unwound up to the function that is doing the catch.
If you don't catch it will end up as an unhandled exception, which will invoke some kind of diagnostic (like a debugger or a exception logger), the full stack and its state at the actual point of failure will be available for inspection.
So if you catch then re-throw an exception that isn't handled elsewhere you rob the diagnostic tool of the really useful info about what actually happened.
With the code the way you've written it for MethodA, there is no difference. All it will do is eat up processor cycles. However there can be an advantage to writing code this way if there is a resource you must free. For example
Resource r = GetSomeResource();
try {
// Do Something
} catch {
FreeSomeResource();
throw;
}
FreeSomeResource();
However there is no real point in doing it this way. It would be much better to just use a finally block instead.
Just rethrowing makes no sense - it's the same as if you did not do anything.
However it gets useful when you actually do something - most common thing is to log the exception. You can also change state of your class, whatever.
Taken as-is, the first option would seem like a bad (or should that be 'useless'?) idea. However, it is rarely done this way. Exceptions are re-thrown from within a Catch block usually under two conditions :
a. You want to check the exception generated for data and conditionally bubble it up the stack.
try
{
//do something
}
catch (Exception ex)
{
//Check ex for certain conditions.
if (ex.Message = "Something bad")
throw ex;
else
//Handle the exception here itself.
}
b. An unacceptable condition has occurred within a component and this information needs to be communicated to the calling code (usually by appending some other useful information or wrapping it in another exception type altogether).
try
{
//do something
}
catch (StackOverflowException ex)
{
//Bubble up the exception to calling code
//by wrapping it up in a custom exception.
throw new MyEuphemisticException(ex, "Something not-so-good just happened!");
}
Never do option A. As Anton says, it eats up the stack trace. JaredPar's example also eats up the stacktrace. A better solution would be:
SomeType* pValue = GetValue();
try {
// Do Something
} finally {
delete pValue;
}
If you got something in C# that needs to be released, for instance a FileStream you got the following two choices:
FileStream stream;
try
{
stream = new FileStream("C:\\afile.txt");
// do something with the stream
}
finally
{
// Will always close the stream, even if there are an exception
stream.Close();
}
Or more cleanly:
using (FileStream stream = new FileStream("c:\\afile.txt"))
{
// do something with the stream
}
Using statement will Dispose (and close) the stream when done or when an exception is closed.
When you catch and throw, it allows you to set a breakpoint on the throw line.
Re-throwing exceptions can be used to encapsulate it into generic exception like... consider following example.
public class XmlException: Exception{
....
}
public class XmlParser{
public void Parse()
{
try{
....
}
catch(IOException ex)
{
throw new XmlException("IO Error while Parsing", ex );
}
}
}
This gives benefit over categorizing exceptions. This is how aspx file handlers and many other system code does exception encapsulation which determines their way up to the stack and their flow of logic.
The assembly A - try catch - block does not make any sense to me. I believe that if you are not going to handle the exception, then why are you catching those exceptions.. It would be anyway thrown to the next level.
But, if you are creating a middle layer API or something like that and handling an exception ( and hence eating up the exception) in that layer does not make sense, then you can throw your own layer ApplicationException. But certainly rethrowing the same exception does not make sense.
Since the classes are in 2 different assemblies, you may want o simply catch the exception for logging it and then throw it back out to the caller, so that it can handle it the way it sees fit. A throw instead of a throw ex will preserve contextual information about where the exception originated. This can prove useful when your assembly is an API/framework where in you should never swallow exceptions unless its meaningful to do so but helpful nonetheless in trouble shooting if it's logged for example to the EventLog.
You can use try{} catch(ex){} block in Method A only if you could catch the specific exception which can be handled in MethodA() (for eg: logging ).
Another option is chain the exception using the InnerException property and pass it to the caller. This idea will not kill the stack trace.