how to catch exception in C# which call a C++ dll - c#

My C# called a method from a C++ dll, after the call returned, my application just gone without any message. want to add try catch to get the reason. how can I do it. Just a try-catch in the method call?
EDIT:
the [HandledProcessCorruptedStateExceptions] is not belong to C#?

An interesting article on exception handling, also with respect to handling corrupted state exceptions:
CLR Inside Out: Handling Corrupted State Exceptions
However, I would assume that there is something wrong either in the way you are calling the native method or in the native method itself. It's best to fix the original problem that is causing the CSE instead of catching exceptions that indicate that your application is no longer in a stable state. You probably will only make things worse by catching such an expcetion. The article mentioned above states:
Even though the CLR prevents you from naively catching CSEs, it's still not a good idea to catch overly broad classes of exceptions. But catch (Exception e) appears in a lot of code, and it's unlikely that this will change. By not delivering exceptions that represent a corrupted process state to code that naively catches all exceptions, you prevent this code from making a serious situation worse.

try{
return (22 / 0); // Cant devise by 0
}catch (System.DivideByZeroException ZeroEx) //Catch type of exception and assign to variable
{
Console.WriteLine("Division by zero attempted!");
Console.WriteLine("Are you sure you wish to continue");
string answer = Console.Read();
}
Like so

Related

How to descern fatal from non fatal .NET Exceptions

I'm writing a general discrete event system simulation library in C#. I'm going to write another library on top of that which will implement a specific kind of discrete event sim. Here is an integral version of the code.
static class Engine
{
[ThreadStatic] internal static uint time;
//...
public static void Run(OnException onException = OnException.PauseAndRethrow,
IList<Type> exceptionsToPass = null)
{
//...
while (!stop)
{
Event e = currentTimeEventQueue.PopEvent();
if (e == null) break;
try {
e.Activate();
}
catch (EngineException ex)
{
// An engine method that shouldn't have been called
// was called, and Activate didn't handle that
// handle this situation...
}
catch (/* fatal exception type*/ ex)
{
throw;
}
catch (Exception ex)
{
// code to decides whether to dismiss exception
// pause, stop, reset based on parameters to this method
}
}
}
}
The question is: Should I specifically catch Exception types that are known to be unrecoverable (that I shouldn't try to handle in any way). What are those Exceptions (I can think of OutOfMemoryException and StackOverflowException). Is there a list of fatal Exceptions? As I remember some of them are uncatchable. So I am interested in a list of fatal Exceptions that can be caught. I just want to rethrow them, and not do anything. On the other hand I want to handle any other type of Exception. Or maybe I need another angle on this.
EDIT: OK, I've made a huge oversight when writing the question. Activate() is abstract. I am writing a general purpose discrete event system simulation library. The engine is working with totally unknown subclasses of Event. So it is calling an absolutely unknown method Activate(), that could throw any kind of exception. I could just ignore this issue, but I want to give control of the process to the caller. As you can see from the parameters to the Run() method, the caller decides what the engine will do if an exception comes from a call to Activate() (it can instruct the engine to ignore and continue, or pause and rethrow, or ...). That is why I am trying to separate fatal from all other Exceptions. If the caller has instructed the engine to ignore any exception that comes from Activate() it would be unwise to catch and ignore fatal exceptions. (there be dragons :) )
Should I specifically catch Exception types that are known to be unrecoverable
No. You shouldn't. If they are unrecoverable you shouldn't try to recover from them.
The rule regarding exceptions is - catch and handle exceptions that you know how to recover from. Let any other bubble up - if this means an application crash, this is probably for the best.
The following is a code smell and shouldn't be coded:
catch (/* fatal exception type*/ ex)
{
throw;
}
No throwable is really "uncatchable"; anything that can be thrown in .NET derives from Exception and so can be caught. However, many things shouldn't be caught. Hence your question; how to tell the difference?
The general rule I follow is "Catch the exceptions that you expect and know how to deal with". This requires you to first know what your code could throw. The MSDN docs are usually pretty good at stating what various framework methods will throw in what situations; your own codebase is likely less well-documented unless you're developing an intermediate library to be consumed by other coders (or your management/leads are anal about proper documentation).
Once you know what the code can throw, determine what, if anything, you should catch. Exception trapping, aka "Pokemon handling" (Gotta catch 'em all) is generally a bad thing because there are legitimate reasons to let your application die a fiery death and make the user restart it. Examples include StackOverflowExceptions, OutOfMemoryExceptions, and various Win32Exceptions detailing some internal failure to provide your program with the requested resources. You usually cannot recover from these in any meaningful way.
Most errors, however, are not that serious. Exceptions are thrown when a file isn't found, or when a network connection is refused or unexpectedly closed, or when you attempt to do something with a type without checking for null (and what happens when the check for null fails? Often you can't continue and must throw an exception of your own). These are things that you should be expecting, catching, and at the very least communicating to the end user in some understandable way.
In many cases, try/throw/catch is a useful tool for expected but not everyday situations; if you receive a timeout exception while waiting for results when usually there's no problem getting results, then don't even tell the user there was a problem; just try again. If you can (should?) plug in some default value when a calculation can't be evaluated (divide by zero, math that could produce non-real results but the code can't handle them, etc etc), then do so.
There is, however, one scenario I can think of where you simply must catch and rethrow, and that's in situations involving database transactions. If you're performing a large "unit of work" with a database transaction handling several persistence operations along the way, then if anything goes wrong, you should roll back the DB transaction. In that case, the operation should be surrounded in a try-catch(Exception) block that catches the exception, rolls back the transaction, and rethrows. Any exception that you can proceed through normally should be handled with a nested try-catch or the condition should be checked for prior to the operation that could fail in that way.
Your question is a reasonable one to ask, but alas there is often no really good answer. A major weakness with the exception paradigm in C++, which unfortunately follows through into other languages and frameworks which borrow from it, is that it encapsulates way too much in the type of an exception object. In C++, this is understandable, since Bjarne Stroustrup wanted to avoid having any non-primitive types be "hard-coded" into the language; given that constraint, the C++ design may have been the best possible. Nonetheless, such a design imposes some serious limitations.
The biggest problem is that code which is considering catching and processing an exception, and then either swallowing or rethrowing it, may be interested in a number of things:
What happened that prevented code from behaving as expected
What actions should be taken in response to the condition
Once various actions have been taken, should the condition be considered "resolved"
Should one adjust one's assumptions about any aspects of the system state beyond what is implied by the method's failing (e.g. if file "foo/bar" couldn't be read, the nature of the failure may impact a decision whether to try reading "foo/boz").
In Java and .net, the expectation is that the exception type should be used to indicate #1 above, and there's no standard means for exceptions to answer #2 and #3, even though they are in many cases far more important than "what happened". If one tries to load a document and something goes wrong, 99% of the time the system will be in the same state as it was before the load attempt, so the exception, regardless of its type, will basically mean "file isn't readable and wan't loaded". Further, in that remaining 1% of the time where something "bad" happens beyond the failure to load the file, it's entirely possible that the exception type will be the same as one that's thrown in the 99%.
Absent some new exception-handling features, one's best bet is probably, to the extent possible, have exceptions that indicate state corruption invalidate the corrupted parts of system state such that all future operations on those parts will likewise throw exceptions. Such behavior will mean that exceptions that code can't handle will end up bringing down the system (since the code will keep trying to use parts of the state that have become corrupted), while allowing code to recover from things it should recover from (e.g. if an exception occurs because of corruption in an object which was being built, and if the exception causes code to abandon the object under construction, such abandonment would suffice to "handle" the exception, and so execution can and should continue).

Catching general exceptions

According to this MSDN article, you should not catch general exceptions. I'm sure there's a stackoverflow question dealing with that, and I understand why it's not a good practice but I just saw this example on another MSDN article today:
using System;
using System.IO;
class Test
{
public static void Main()
{
try
{
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
}
}
Is there any justification to catching a general exception in that example or is it just that they were lazy to write an example catching all the specific exceptions?
In this case, this is an example and is a poor one at that, like many code examples on MSDN.
This should be catching an IO Exception instead of the base class.
The only place it would make sense to catch Exception is in a global exception handler for logging, provided you rethrow.
Rule "CA1031: Do not catch general exception types" is utterly useless. (not it's intent per se, but it's implementation and description)
In this specific case it may be feasible to catch the more specific IOException as it covers "most" of the exceptions the StreamReader constructor is documented to throw.
(oh wait, and then you also need to factor in all the stuff that could be thrown by ReadToEnd)
(oh, wait, maybe it's a legitimate exception catch case to have an ArgumentException for the case the passed string is empty -- that is, I want to catch that generically and not explicitly test for it.)
Except that:
The set of exceptions that possibly can be thrown from any function is
often poorly documented
potentially unbounded (there may lurk some OutOfMemoryException; bugs in the implementation that lead to other exceptions, etc.)
largely irrelevant (modulo some bug catching with things like ArgumentNullException)
Given roughly the example given, all you care about is that reading the file failed - IFF it failed, you need to communicate that up the call chain.
To repeat: You want to communicate up the call chain that reading the file failed and why is only secondary.
When did reading (processing) the file fail: When any exception is thrown.
So what you really want to do is catch any exception, contextualize it with what you wanted to do (say, add the filename) and then return or rethrow something that indicates what went wrong and why it went wrong ( that would be the actual "inner" exception).
For this, the example is (nearly) spot on:
"Up the call chain" in this case is the user directly at the console
It "returns" the error as a string to be read by the "user", which is appropriate for a simple consle program.
It communicates what went wrong clearly. (It should include the filename passed to StreamReader though.)
It includes why it went wrong, namely the exception message. (It possibly should also include the call stack.)
By example:
Say that this example is slightly more complex and the file name is user provided. The the string being empty is then (a) a normal case and maybe (b) a user error that might not warrant special handling in the code, because the general handling provided -- that is, reporting that reading the file failed -- is totally enough.
By catching only IOException as recommended above, the user entering an empty filename would either crash the application or require an additional catch block that would essentially do the same thing as the other catch block: Report that reading the file failed and why.
Independent observations: Found this nice piece: http://www.codeproject.com/Articles/7557/Exception-Handling-in-C-with-the-quot-Do-Not-Catch where the author is certainly more constructive than my "utterly useless" statement but essentially has a similar conclusion (with a different, certainly valid, solution): (emph. added)
If we follow Microsoft's guidelines then we have to catch only those
exceptions that could be triggered by the File.Copy method. If you
look in the .NET Framework's Class Library, you'll see that this is
UnauthorizedAccessException, (...). If you
ask me, catching all these exceptions individually is not doable. All
I wanted to know is whether or not a file copy failed or not. It would
be sufficient to only capture IOException, ArgumentException and
NotSupportedException (because all the other exceptions derive from
these three exceptions) but to know this I have to read the
documentation again. I really don't want to go through that much
trouble to simply copy a file.
The guideline assumes that we know all the exceptions that can be
thrown by the task executed. Copying a file is a very simple operation
that is properly documented by Microsoft. But what if we're using some
third-party tool? The stability of our unattended tool depends on the
quality of the documentation of this tool. If this third-party forgets
to mention one of the exceptions that their tool throws in the
documentation, then our unattended application could stop prematurely.
Examples should be clear and simple. This is the example of clear and simple example. But we should not catch general exeption in our code.

General Exception Handling Strategy for .NET

I’m used to having try/catch blocks in every method. The reason for this is so that I can catch every exception at the point of infraction and log it. I understand, from my reading and conversations with others, that this isn’t a popular view. One should only catch what one is prepared to handle. However, if I don’t catch at the point of infraction, then it would be possible to never log that infraction and know about it. Note: When I do catch and don’t handle, I still throw. This allows me to let the exception propagate to something that will handle it, yet still let me log it at the point of infraction.
So... How does one avoid try/catch in every method, yet still log the error at the point at which it occurred?
No, don't catch everything. Exceptions propagate higher up on the stack. All you have to do is make sure that the exception is caught before it gets to the top of the stack.
This means, for instance, that you should surround the code of an event handler with a try/catch block. An event handler may be the "top of the stack". Same for a ThreadStart handler or a callback from an asynchronous method.
You also want to catch exceptions on layer boundaries, though in that case, you might just want to wrap the exception in a layer-specific exception.
In the case of ASP.NET, you may decide to allow ASP.NET Health Monitoring to log the exception for you.
But you certainly don't ever need to catch exceptions in every method. That's a major anti-pattern. I would loudly object to you checking in code with that kind of exception handling.
You can see everything at stack trace - no need to try/catch every method.
Stick to few rules:
Use try/catch only if you want to use a custom exception type
Define a new exception type only if upper levels needs to know that
Try/catch at top level instead of doing that for each method
OK, having read all the answers saying you should have a single try/catch at the top level, I'm going to weigh in with an alternative view.
I wouldn't put a try/catch in every method, far from it. But I would use a try/catch around sections of code that I expected to fail (e.g. opening a file), and where I wanted to add additional information to the exception (to be logged higher up the chain).
A stack trace saying and a message saying "permission denied" might be enough to allow you as a programmer to figure out what went wrong, but my goal is to provide the user with meaningful information, such as "Could not open file 'C:\lockedfile.txt'. Permission denied.".
As in:
private void DoSomethingWithFile(string filename)
{
// Note: try/catch doesn't need to surround the whole method...
if (File.Exists(filename))
{
try
{
// do something involving the file
}
catch (Exception ex)
{
throw new ApplicationException(string.Format("Cannot do something with file '{0}'.", filename), ex);
}
}
}
I'd also like to mention that even the people saying "only have one try/catch" would presumably still use try/finally throughout their code, since that's the only way to guarantee proper cleanup, etc.
Catching and rethrowing an exception that you cannot handle is nothing more than a waste of processor time. If you can't do anything with or about the exception, ignore it and let the caller respond to it.
If you want to log every exception, a global exception handler will do just fine. In .NET, the stack trace is an object; its properties can be inspected like any other. You can write the properties of the stack trace (even in string form) to your log of choice.
If you want to ensure that every exception is caught, a global exception handler should do the trick. In point of fact, no application should be without one.
Your catch blocks should only catch exceptions that you know that you can gracefully recover from. That is, if you can do something about it, catch it. Otherwise, let the caller worry about it. If no callers can do anything about it, let the global exception handler catch it, and log it.
I definitely don't use a try catch wrapper around every method (oddly enough, I did when I first started but that was before I learned better ways).
1) To prevent the program from crashing and the users losing their info, I do this
runProgram:
try
{
container.ShowDialog();
}
catch (Exception ex)
{
ExceptionManager.Publish(ex);
if (MessageBox.Show("A fatal error has occurred. Please save work and restart program. Would you like to try to continue?", "Fatal Error", MessageBoxButtons.YesNo) == DialogResult.Yes)
goto runProgram;
container.Close();
}
container is where my application starts so this basically puts a wrapper around my entire app so that nothing causes a crash that can't be recovered. This is one of those rare instances where I don't really mind using a goto (it is a small amount of code and still quite readable)
2) I only catch exceptions in methods where I expect something could go wrong (such as a timeout).
3) Just as a point of readibility, if you have a try catch block with a bunch of code in the try section and a bunch in the catch section, it is better to extract that code to a well named method.
public void delete(Page page)
{
try
{
deletePageAndAllReferences(page)
}
catch (Exception e)
{
logError(e);
}
}
To do it at the point of occurrence, you would still need a try/catch. But you don't necessarily need to catch the exceptions everywhere. They propagate up the call stack, and when they are caught, you get a stack trace. So if a problem emerges, you can always add more try/catches as needed.
Consider checking out one of the many logging frameworks that are available.
I don't think you need to catch everything at the point of infraction. You can bubble up your exceptions, and then use the StackTrace to figure out where the point of infraction actually occurred.
Also, if you need to have a try catch block, the best approach I've heard is to isolate it in a method, as to not clutter the code with huge try catch blocks. Also, make as few statements as possible in the try statement.
Of course, just to reiterate, bubbling up your exceptions to the top and logging the stacktrace is a better approach than nesting try-catch-log-throw blocks all throughout your code.
I would look into using ELMAH for exception handling, which is pretty much a concept of "let exceptions happen". ELMAH will take care of logging them and you can even set it to email you when exceptions for a certain project reach or exceed a specific threshold. In my department, we stay as far away from try/catch blocks as possible. If something is wrong in the application, we want to know right away what the issue is so we can fix it, instead of repressing the exception and handling it in code.
If an exception happens, that means that something isn't right. The idea is to make your application do only what it should do. If it's doing something different and causing exceptions, your response should be to fix the reason it's happening, not let it happen and handle it in code. This is just my/our philosophy and it's not for everyone. But we've all been burned way too many times by an application "eating" an exception for some reason or another and no one knows that something is wrong.
And never, ever, EVER catch a general Exception. Always, always, always catch the most specific exception so that if an exception is thrown, but it's not the type you're expecting, again, you'll know because the app will crash. If you just catch (Exception e), then no matter what type of exception is thrown, your catch block will now be responsible for responding to every single type of exception that could possibly be thrown. And if it doesn't, then you run into the whole "eating" exceptions, where something is going wrong but you never know until it is likely too late.
How does one avoid try/catch in every method, yet still log the error at the point at which it occurred?
It depends on the hosting env. Asp.Net, WinForms, and WPF all have different ways of capturing unhandled exceptions. But once the global handler is passes an exception instance you can determine the point of throw from the exception, as each exception includes a stacktrace.
Realistically, avoid granular try/catches. Allow the exception to traverse upwards in the stack and be caught in as high a level as possible. If you have a specific point of concern, then place logging in the immediate catch, if you are worried about the exception cascading - although you would still be able to resolve these by drilling into the inner exceptions.
Exception handling should not be an afterthought. Make sure that you do it consistently. I have seen a lot of people put a broad try/catch from the beginning to the end of every method and catch the general exception. People think that this helps them get more information, when in fact, it doesn't. More is less in some cases, as less is more. I never get tired of the axiom that "Exceptions should be used to note exceptional behavior." Recover if you can, and try to reduce the number of overall exceptions. Nothing is more frustrating when you are trying to troubleshoot an issue and seeing hundreds of the same NullReferenceException, or similar, when something goes wrong.
Exceptions are implemented so that they have no cost unless thrown.
This means to me that performance ramifications is not a strong argument against. Exceptional conditions usually are ... exceptional.

C# try/catch nightmare

I have a application with similar code (not written by me)
try
{
EnumerateSomeCoolHardwareDevice();
}
catch (Exception ex)
{
}
UPDATE - This is .NET C# & EnumerateSomeCoolHardwareDevice() is using SerialPort?
I know how bad this code is but it works like this for a reason!
My question thou: I can see that it crashes somewhere in the EnumerateSomeCoolHardwareDevice(); but it doesn't get caught by the Catch (...) - It just crashes with the send report dialog! This also currently only happen in the release build... Is their ANY reason why my exception will NOT be caught by the catch (...)?
My guess is that you're not getting an Exception in your language/framework but rather EnumerateSomeCoolHardwareDevice() does weird things that simply cause the OS to kill your process. Remember that hardware details are abstracted by frameworks like Java and .NET, so whenever you do something with hardware directly, you're probably relying on unmanaged resources ... and whatever goes wrong there can kill you, catch or not.
One possible reason would be if the EnumerateSomeCoolHardwareDevice() function uses threading. If an exception is thrown in a thread and isn't handled within it's thread then it can crash an application. This simple app can demonstrate what I mean:
public static void testThread()
{
throw new Exception("oh god it's broken");
}
static void Main(string[] args)
{
try
{
Thread thread = new Thread(testThread);
thread.Start();
Console.ReadKey(); //Just to make sure we don't get out of the try-catch too soon
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
If you run that the app will crash and burn rather than catching the exception as you might expect.
In .NET catch (Exception ex) will only catch .NET exceptions, not native exceptions.
This question (catching native exceptions in C#) may help.
Assuming .NET, if EnumerateSomeCoolHardwareDevice uses Win32 methods via PInvoke (to access the hardware) and an error occurs, most Native methods return an error code. If that error code is not handled, and another native method is called anyway (perhaps with empty out parameters from the failed call), a serious native error (such as bad memory access or something similar) can cause a straight program crash, no exception thrown.
Have you tried the attribute
assembly:RuntimeCompatibility(WrapNonExceptionThrows = true)
That should wrap any non-.Net exceptions into System.Exception so it will be catched in your code.
If it is only happening on the production machine and not the dev machines then it could be down to DLL mismatches. Double check ALL the referenced DLLs and frameworks are the same version.
Secondly if the error is not being thrown by the EnumerateSomeCoolHardwareDevice() then it will crash the app as there is no way for the exception to get back up the stack (or thats my understanding of try/catches) in my experience this has happened to me before.
Lastly, the microsoft error report usually allows you to inspect what will be sent to MS, this should let you see where the error happened and why (assuming it has readable information within it).
Check the Event Viewer as the error should also be logged there, and normally provides an invaluable source of detail regarding the error and with a bit of digging through the error listed there you should be able to trace the fault.
If you are in .Net version 1.1 use a no parameters catch block like
catch{
...
}
Prior to .Net 2.0 there could be native exceptions that do not derive from System.Exception.
Also hook to appdomain unhandled exception event and see what happens.
There may be a try..catch inside EnumerateSomeCoolHardwareDevice().
If the exception is caught and handled there, the outer exception won't be hit unless the Exception is thrown again.
(Assuming Java) Both Error and Exception are subclasses of Throwable. If there is an assertion failing in EnumerateSomeCoolHardwareDevice() for example you will get an Error.
My guess is that there's a stack overflow happening. The .NET VM simply shuts down Release build processes that encounter a stack overflow, no CLR exceptions thrown. There's probably an internal try / catch inside that function that catches StackOverflowException one way or other, that's why it's not propagating to your code in Debug builds either.
The easiest way to figure out what's going on is by making a debug build, attaching a debugger and instructing the debugger to break before any exceptions are thrown (in Visual Studio, Debug/Exceptions and tick "Thrown" for "Common Language Runtime Exceptions" and possibly other ones as well, in cordbg.exe "catch exception")
If it is crashing madly and is using a SerialPort object then it is probably because at some point it skips onto a background thread and an exception happens here. IIRC the .DataReceived event or however you get information back from a serial port returns data on a background thread. Should an exception be thrown in this routine then the entire application will bail.
Find the background thread and put some exception handling round it.
What types of exception have you seen behaving in this way? Do you have a list of them?
Some exceptions will keep propgating up the call stack, even if they've been caught in a catch block, such as ThreadAbortException.
Others are essentially unhandleable, such as StackOverflowException or ExecutionEngineException.
If it is one of these (or some others I have probably missed), then the behaviour is probably as expected. If it is some others, then a deeper look with more information will be necessary.

What is the right way to pass on an exception? (C#) [duplicate]

This question already has answers here:
Best practices for catching and re-throwing .NET exceptions
(11 answers)
Closed 9 years ago.
I'm wondering what the correct way is to pass on an exception from one method to another.
I'm working on a project that is divided into Presentation (web), Business and Logic layers, and errors (e.g. SqlExceptions) need to be passed down the chain to notify the web layer when something goes wrong.
I've seen 3 basic approaches:
try
{
//error code
}
catch (Exception ex)
{
throw ex;
}
(simply rethrow)
try
{
//error code
}
catch (Exception ex)
{
throw new MyCustomException();
}
(throw a custom exception, so that a dependency on the data provider is not passed on)
and then simply
//error code
(not doing anything at all, letting the error bubble up by itself)
Naturally there's some logging happening in the catch block too.
I prefer number 3, while my colleague uses method 1, but neither of us can really motivate why.
What are the advantages/disadvantages of using each method? Is there a better method I don't know of? Is there an accepted Best Way?
If you do nothing you should simply let it go upper where some one will handle it.
You can always handle a part of it (like logging) and re-throw it. You can re-throw by simply sending throw; without having to explicit the ex name.
try
{
}
catch (Exception e)
{
throw;
}
The advantage to handle it is that you can ensure that some mechanism is there to notify you that you have an error where you do not suspect to have one.
But, in some case, let say a Third Party, you want to let the user handle it and when it's that case you should let it continue to bubble up.
I think you should start with a slightly different question
How do I expect other components to interact with exceptions thrown from my module?
If the consumers are quite capable of handling the exceptions thrown by the lower / data layers then quite simply do nothing. The upper layer is capable of handling the exceptions and you should only do the minimum amount necessary to maintain your state and then rethrow.
If the consumers cannot handle low level exceptions but instead need a bit higher level exceptions, then create a new exception class which they can handle. But make sure to pass on the original exception a the inner exception.
throw new MyCustomException(msg, ex);
The correct way to re-throw an exception in C# is like below:
try
{
....
}
catch (Exception e)
{
throw;
}
See this thread for specifics.
Only use try/catch blocks around exceptions you expect and can handle. If you catch something you cannot handle, it defeats the purpose of try/catch which is to handle expected errors.
Catching big exception is rarely a good idea. The first time you catch an OutOfMemoryException are you really going to be able to gracefully handle it? Most API's document the exceptions each method can throw, and those should be the only ones handled and only if you can gracefully handle it.
If you want to handle the error further up the chain, let it bubble up on its own without catching and rethrowing it. The only exception to this would be for logging purposes, but logging at every step is going to do an excessive amount of work. It is better to just document where exceptions your public methods can be expected to allow to bubble up and let the consumer of your API make the decision on how to handle it.
No one has yet pointed out the very first thing you should be thinking of: what are the threats?
When a back-end tier throws an exception, something terrible and unexpected has happened. The unexpected terrible situation might have happened because that tier is under attack by a hostile user. The last thing you want to do in that case is serve up to the attacker a detailed list of everything that went wrong and why. When something goes wrong on the business logic tier the right thing to do is to carefully log all information about the exception and replace the exception with a generic "We're sorry, something went wrong, administration has been alerted, please try again" page.
One of the things to keep track of is all the information you have about the user and what they were doing when the exception happened. That way if you detect that the same user always seems to be causing problems, you can evaluate whether they are likely to be probing you for weaknesses, or simply using an unusual corner of the application that wasn't sufficiently tested.
Get the security design right first, and only then worry about diagnosis and debugging.
I've seen (and held) various strong opinions about this. The answer is that I don't think there currently is an ideal approach in C#.
At one point I felt that (in a Java-minded way) the exception is part of the binary interface of a method, as much as the return type and parameter types. But in C#, it simply isn't. This is clear from the fact that there is no throws specification system.
In other words, you can if you wish take the attitude that only your exception types should fly out of your library's methods, so your clients don't depend on your library's internal details. But few libraries bother to do this.
The official C# team advice is to catch each specific type that might be thrown by a method, if you think you can handle them. Don't catch anything you can't really handle. This implies no encapsulation of internal exceptions at library boundaries.
But in turn, that means that you need perfect documentation of what might be thrown by a given method. Modern applications rely on mounds of third party libraries, rapidly evolving. It makes a mockery of having a static typing system if they are all trying to catch specific exception types that might not be correct in future combinations of library versions, with no compile-time checking.
So people do this:
try
{
}
catch (Exception x)
{
// log the message, the stack trace, whatever
}
The problem is that this catches all exception types, including those that fundamentally indicate a severe problem, such as a null reference exception. This means the program is in an unknown state. The moment that is detected, it ought to shut down before it does some damage to the user's persistent data (starts trashing files, database records, etc).
The hidden problem here is try/finally. It's a great language feature - indeed it's essential - but if a serious enough exception is flying up the stack, should it really be causing finally blocks to run? Do you really want the evidence to be destroyed when there's a bug in progress? And if the program is in an unknown state, anything important could be destroyed by those finally blocks.
So what you really want is (updated for C# 6!):
try
{
// attempt some operation
}
catch (Exception x) when (x.IsTolerable())
{
// log and skip this operation, keep running
}
In this example, you would write IsTolerable as an extension method on Exception which returns false if the innermost exception is NullReferenceException, IndexOutOfRangeException, InvalidCastException or any other exception types that you have decided must indicate a low-level error that must halt execution and require investigation. These are "intolerable" situations.
This might be termed "optimistic" exception handling: assuming that all exceptions are tolerable except for a set of known blacklisted types. The alternative (supported by C# 5 and earlier) is the "pessimistic" approach, where only known whitelisted exceptions are considered tolerable and anything else is unhandled.
Years ago the pessimistic approach was the official recommended stance. But these days the CLR itself catches all exceptions in Task.Run so it can move errors between threads. This causes finally blocks to execute. So the CRL is very optimistic by default.
You can also enlist with the AppDomain.UnhandledException event, save as much information as you can for support purposes (at least the stack trace) and then call Environment.FailFast to shut down your process before any finally blocks can execute (which might destroy valuable information needed to investigate the bug, or throw other exceptions that hide the original one).
I'm not sure that there really is an accepted best practices, but IMO
try // form 1: useful only for the logging, and only in debug builds.
{
//error code
}
catch (Exception ex)
{
throw;// ex;
}
Makes no real sense except for the logging aspect, so I would do this only in a debug build. Catching an rethrowing is costly, so you should have a reason for paying that cost other than just that you like looking at the code.
try // form 2: not useful at all
{
//error code
}
catch (Exception ex)
{
throw new MyCustomException();
}
This one makes no sense at all. It's discarding the real exception and replacing it with one that contains less information about the actual real problem. I can see possibly doing this if I want to augment the exception with some information about what was happening.
try // form 3: about as useful as form 1
{
//error code
}
catch (Exception ex)
{
throw new MyCustomException(ex, MyContextInformation);
}
But I would say in nearly all cases where you are not handling the exception the best form is to simply let a higher level handler deal with it.
// form 4: the best form unless you need to log the exceptions.
// error code. no try - let it percolate up to a handler that does something productive.
Normally you'd catch only exceptions which you expect, can handle and let application work in a normal way further. In case you'd like to have some additional error logging you'll catch an exception, do logging and rethrow it using "throw;" so the stack trace is not modified. Custom exceptions are usually created for the purpose of reporting your application specific errors.

Categories