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.
Related
When to examine the InnerException property of the Exception class and its derivatives? Microsoft's "Best practices for exceptions" doesn't provide any advise on when to examine for inner exceptions. Should I do it only when exceptions are rethrown and caught in my code? Should I do it always, even when I enclose in try-catch block standard functions like System.IO.File.Move?
Who might use such a feature?
Sometimes, developers convert one exception (typically one definied by Microsoft) into another exception (typically an exception defined on their own).
This can make an API simpler, e.g. as in the example you have given with File.Move(). Instead of the 7 possible Microsoft exceptions, such an API could just throw a simple "That didn't work" exception with details inside, so your code only needs to handle one type of exception.
When to use it?
I would look into them during the development phase when using the 3rd party framework. If they tend to be empty, there's no value in writing code for it.
If you write a logger / tracer or generic debug output, I would definitely consider it.
Exceptions I know that have InnerExceptions:
TargetInvocationException
AggregateException
Ultmately the answer here is simply: whenever it is useful for you to do so, which is entirely contextual. For the vast majority of cases, it isn't actually worth checking much on the exception at all - other than reporting it; just "do the thing, oops, failed" - you should usually have more using and finally than catch, IMO - because usually there isn't anything useful you can do with an exception except bubble it upwards.
However, in some cases, there is useful context. Classic examples would be AggregateException, TargetInvocationException and TypeInitializationException or anything coming from XmlSerializer. Those are pretty rare, so you wouldn't want to start checking for them explicitly unless you have very good reason to expect them. In terms of your general error reporting code: yes it makes sense to log the inner exceptions, but .ToString() usually does that automatically, IIRC.
As an example from some real code involving InnerException - there is a scenario in my network code where I don't care about a very specific situation only detectable via the combination of outer and inner exception; when does this job for me:
try
{
await _server.RunClientAsync(connection.Transport).ConfigureAwait(false);
}
catch (IOException io) when (io.InnerException is UvException uv && uv.StatusCode == -4077)
{ } //swallow libuv disconnect
(everything other than that scenario is bubbled)
I'm new in a developement for Windows 8 and C#, but I have certain experience with Java Programming.
So, when I try to make some Json parser (for example) in java, I can't do it without use a try - catch block, and this way I can handle the exception, but when I try to do the same in c# (Windows 8) and I don't use the try - catch block it works too, like this:
if (json != null)
{
JObject jObject = JObject.Parse(json);
JArray jArrayUsers = (JArray)jObject["users"];
foreach (JObject obj in jArrayUsers)
{
ListViewMainViewModel user = new ListViewMainViewModel(
(String)obj["email"],
(String)obj["token"],
(String)obj["institution"],
(String)obj["uuidInstitution"]);
usersList.Add(user);
}
return usersList;
}
}
As I know the right way is to catch JsonReaderException, but Visual Studio never warned me on that. I would like to know if there's a easy way to know if some method throw an exception, like is on java using eclipse (it's mandatory implement try-catch block or code wont compile)
You will have to consult the documentation for that. C# lacks a throws keyword.
The term for what you are looking for is checked exceptions, and more info can be found in the C# FAQ.
In C# you are responsible for handling exceptions - which IMHO is the better way of going about it than the Java implementation. In effect, an exception should be, well exceptional, that is: It isn't something you should just always expect to happen.
Consider this weirding (yet, common) anti-pattern:
try {
} catch (Exception ex) { /* Handler goes here */ }
What exactly does that mean? Are you really going to handle every single exception that passes through here? Even stuff like OutOfMemoryExceptions? That's nuts. The only thing this sort of pattern will lead to is suppressing legitimate exceptions that really ought to bring down the application - this is fairly similar to the Java approach.
Think of an Exception as being a flag to the programmer that says 'hey, the environment just entered an impossible state'. For example, if I try to divide by zero and the system throws a DivideByZeroException, then rightly the system should alert you to this, because this is a failure - one the system can't just 'figure it's way out of' - and if you simply suppress the issue, how is that really helping? In the end this is counter-productive, in that all you're doing is masking over what is really an impossible application state. If you do this a lot in your application, then it eventually just devolves into a sludge of toxic wrong-ness. Yuck!
Exceptions also take up a lot of screen real estate. Sometimes I wish they would make the try/catch/finally blocks a little more streamlined, but then I remember that doing so would encourage people to use them more, so I repent of that position pretty quick.
Exceptions are useful programmer-to-programmer notifications saying that something you're doing doesn't make sense. Obviously we should never pass raw exceptions to the user because they won't know what to do with them. At the same time, you don't want to try to handle every single exception on the face of the earth, because 'handling' in this sense typically transforms into 'suppression', which is way worse than just letting the application fail (gracefully).
C#, as has been mentioned, does not have checked exceptions, and thank goodness.
The idea of checked exceptions sounds great on its face, but talk to anyone who is forced to use them by language or runtime, and they'll say there are three big problems with checked exceptions:
They impose their will upon the consuming coder. Checked exceptions, by their definition, are expected to be handled before they are thrown out of the runtime. The runtime is in effect telling the coder "you should know what to do when I throw this, so do so". First off, think about it; you are told to expect something that happens in exceptional cases by its very definition. Second, you're expected to somehow handle it. Well, that's all well and good when you actually have the ability to address the problem the exception indicates. Unfortunately, we don't always have that ability, nor do we always want to do everything we should. If I'm writing a simple form applet that performs a data transformation, and I just want my application to die a fiery death if there's any problem, I can't just not catch anything; I have to go up all possible call stacks of every method that could throw something and add what it could throw to the throws clause (or be extremely lazy and put a "throws Exception" clause on every method of my codebase). Similarly, if my app is constructed such that I can't throw out a particular exception, perhaps because I'm implementing an interface beyond my control that doesn't specify it as a potential throwable, then my only options are to swallow it entirely and return a possibly invalid result to my callers, or to wrap the exception in an unchecked throwable type like a RuntimeException and throw it out that way (ignoring the entire checked exception mechanism, which is not recommended of course).
They violate SOLID, especially the Open-Closed Principle. Make a change that adds a checked exception to your code, and if you can't handle said exception, all usages of your method must either handle it or mark themselves as throwing the exception. Usages which rethrow must be handled by their own callers or they have to be marked as throwing the same exception. By making a change as surgical as calling an alternate method in a particular line of code, you now have to trace up all possible call stacks and make other changes to code that was working just fine, just to tell them your code could conceivably throw an exception.
They create leaky abstractions by definition. A caller consuming a method with a "throws" clause must, in effect, know these implementation details about its dependency. It must then, if it is unwilling or unable to handle these errors, inform its own consumers about these errors. The problem is compounded when the method is part of an interface implementation; in order for the object to throw it, the interface must specify it as a throwable, even if not all of the implementations throw that exception.
Java mitigates this by having a multilevel hierarchy of Exception classes; all I/O-related exceptions are (supposed to be) IOExceptions, for instance, and an interface with methods that have IO-related purposes can specify that an IOException can be thrown, relieving it of the responsibility to specify each specific child IOException. This causes almost as many problems as it solves, however; there are dozens of IOExceptions, which can have very different causes and resolutions. So, you must interrogate each IOException that you catch at runtime to obtain its true type (and you get little or no help identifying the specific ones that could be thrown) in order to determine whether it's something you can handle automatically, and how.
EDIT: One more big problem:
They assume try-catch is the only way to handle a possible exception situation. Let's say you're in C# in an alternate universe where C# has Java-style checked exceptions. You want your method to open and read a file given a filename passed into it by the caller. Like a good little coder, you first validate that the file exists in a guard clause, using File.Exists (which will never throw an exception; in order to return true, the path must be valid, the file specified at the path must exist, and the executing user account must have at least read access to the folder and file). If File.Exists returns false, your method simply returns no data, and your callers know what to do (say this method opens a file containing optional config data, and if it doesn't exist, is blank or is corrupted, your program generates and uses a default configuration).
If the file exists, you then call File.Open. Well, File.Open can throw nine different types of exceptions. But none of them are likely to occur, because you already verified using File.Exists that the file can be opened read-only by the user running the program. The checked exception mechanism, however, wouldn't care; the method you're using specifies it can throw these exceptions, and therefore you must either handle them or specify that your own method can throw them, even though you may take every precaution to prevent it. The go-to answer would be to swallow them and return null (or to forget the guard clause and just catch and handle File.Open's exceptions), but that's the pattern you were trying to avoid with the guard clause in the first place.
None of this even considers the potential for evil. A developer might, for instance, catch and encapsulate an unchecked exception as a checked one (for instance, catching a NullPointerException and throwing an IOException), and now you have to catch (or specify that your method throws) an exception that isn't even a good representation of what's wrong.
As far as what to use instead in C#, the best practice is to use XML documentation comments to inform the immediate caller using your method that an exception could potentially be thrown from it. XML-doc is the .NET equivalent to JavaDoc comments, and is used in much the same way, but the syntax is different (three forward slashes followed by the comments surrounded with a system of XML tags). The tag for an exception is easy enough to specify. To efficiently document your codebase, I recommend GhostDoc. It will only generate exception comments for exceptions explicitly thrown from inside the method being documented, however, and you'll have to fill in some blanks.
I'm not a java developer, but from the answers here it seems as though the Java implementation is a burden to clients of those methods. However, C# missed an opportunity (Java-like or otherwise) to communicate to the caller the type of exceptional outcomes that could happen, as authored by the developer of the method, allowing me the caller to handle it appropriately.
Since this construct isn't built into the language, I would suggest to library developers that you adopt a wrapper class and use it as the return type for any methods that could go awry. Using said class as the return type in lieu of exceptions, clients can reason about what to expect when calling the method, as it is clearly defined in the method signature. Also, using the wrapper would allow a method to tell a client why something went awry in a way does not break the flow like exceptions do.
More on this subject here: http://enterprisecraftsmanship.com/2015/03/20/functional-c-handling-failures-input-errors/
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).
I have a question reagrding proper programming practice when dealing with exceptions.
We have production code like:
try
{
File.Copy(src,dest);
}
catch(Exception ex)
{
ShowMessageToUser(ex.Message);
}
Is this a good practice? I thought that we should always make use of specialized exceptions and catch them....on the other hand, I do realize that File.Copy can throw several different exceptions and it will be a pain to write a catch block for every exception...? So what should be done in this case....Is there a set of file specific excepion collections that we can use to catch?
Thanks , any comments are welcome.
As a general practice, I would say this is not a good practice. Personally, I would handle this with separate exceptions, and only handle the exceptions you can be handle correctly.
In this specific scenario, I would also avoid this. I would prefer to handle the explicit exception types, if for no other reason than to customize the message to the user.
This is mainly because exception messages are really not intended for an end user - they're messages meant to be interpreted by a developer. I feel that directly showing an exception message to a user, especially for an operation where an exception is likely, is a bad practice.
You should handle each exception, and provide a meaningful message to the user that makes sense in the context of this operation.
File.Copy can only throw 8 types of exceptions - handling every one, with a message, is only 32 lines of code - that's really not that much when you consider the extra benefit of having a clear, meaningful message in all cases presented to the end user.
IO is generally a pain for this reason- there are so many things that can go wrong. It would be best for you to:
Do everything you can to avoid exceptions by checking all parameters before calling File.Copy. Remember that in .Net exceptions can have severe performance costs due to the generation of a stack trace.
Catch the exceptions that you know you are capable of handling. For some exceptions you might want to display an error message and ask the user for new input.
If you can't handle an exception right there, do not catch it! Exception swallowing is the source of all evil. Reporting an error message is only slightly better than exception swallowing and will only confuse the end user.
It may seem like a lot of work, but sometimes a lot of work is necessary to produce a stable program.
You use specialized exceptions in order to perform different actions based on the type of error you got. If all you want is to show the user the default error message... then your code is sufficient.
But let's say for example that you would like to log the exception if it happened because of security issues... you would write something like:
catch (PermissionDeniedException ex)
{
Log(ex.foo);
ShowMessageToUser(ex.Message);
}
catch(Exception ex)
{
ShowMessageToUser(ex.Message);
}
And remember to always go from more specific to more general exceptions.
Yes that's a bad Practice and you should use specific Exceptions and then general Exception lower the catch block.
If you feel that they are too many then you should at least create catch blocks for most Anticipated file Specific Exception and then have usual Exception catch block
Your example is very easy to implement, but hardly best practices. As a general rule
Only catch Exceptions you are actually interested in handling at this point. Let everything else bubble on to be handled elsewhere.
You can also use superclasses to catch a specific group of exceptions.
Do not use exceptions for things that are not errors. For example, if the user supplies the file name for the copy, you can check beforehand if the file exists, instead of relying on an exception. Exceptions are for "exceptional circumstances", not for foreseeable conditions.
If you're hacking a quick script, however, feel free to use the exception as in your example ;-)
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.