Which is best: Code Snippet 1 or Code Snippet 2 ? And Why?
/* Code Snippet 1
*
* Write try-catch in function definition
*/
void Main(string[] args)
{
AddMe();
}
void AddMe()
{
try
{
// Do operations...
}
catch(Exception e)
{
}
}
/* Code Snippet 2
*
* Write try-catch where we call the function.
*/
void Main(string[] args)
{
try
{
AddMe();
}
catch (Exception e)
{
}
}
void AddMe()
{
// Do operations...
}
The real question to ask is "What is AddMe's contract to the rest of the world?" If AddMe represents the be-all do-all of an interface and correctly handles any exception that encounters in the appropriate way, then sure - let it catch it. If AddMe doesn't or can't know what to do with an exception, then it should throw and defer the handling to the calling code.
It depends, as usual.
In Snippet #1, the error handling is reusable. In Snippet #2, it is not, but that is better in cases where you want to use different error handling in different places.
Other than that, they are identical.
they will operate the same however Most would prefer to catch the logic inside the method if thats where it will be thrown from. Just a best practice though.
There's not best universal way. It depends on how you're going to handle your exceptions.
Do you plan on using a global logger in your main application? The you should have a try/catch block in your main method, and log exceptions there.
You can still try/catch in internal methods if you need to do other stuff with the exceptions, but remember to rethrow them, or else the logger in the main method won't have anything to log.
And remember, to rethrow correctly, use:
throw;
and not:
throw e;
Because the former keeps all the stack trace, while the latter doesn't.
IMHO, allow methods to throw exceptions. Don't attempt to hide when things go wrong. When they do it is up to the client to decide how they'd like to handle the exception. The reasoning for this is because each application may want to do something different with the exception.
TL,DR; Catch exceptions when you can do something about the exception, otherwise let them flow up the call stack until something else will handle them. If the exception cannot be handled by any particular part of your application, your application error event method should handle all the logging for you. Your logging functionality will be your final net for dealing with exceptions.
I've worked with a few shops that require try catch logic on EVERY method, and I learned that the Exception object does a better job watching your call stack than you can.
My other rule of thumb is notify the user of exceptions on user trigger events. So event based or command based captures would be a great place to catch, notify, then re-throw the same exception. (IE throw; NOT throw ex;)
There are already good answers to this question, coming ultimately down to "it depends", but I want to add a thought that I believe greatly influences which method is better for any given situation.
In your code snippet examples, but of your catches are catch (Exception e) {} as opposed to, say, catch (IOException e) or catch (NullReferenceException, or some other narrower exception type. The kind(s) of exception(s) you expect from the code in the try block will make a difference in the way you want to handle it. Especially if you have more than one type to consider, as could be the case if you handle exceptions outside of the subroutine - a large enough upper-level try block could have several different types of exceptions to handle, and start to run the risk of making the code messy.
My general rule of thumb, overall, is that if the exception is a non-critical error (especially if caused by invalid user input), I can handle it in the subroutine and keep the system running. On the other hand, if the exception means the program needs to close, I handle it higher up.
Related
When we wrap a bunch of statements in a try/catch and one of these issues an exception, within the catch we have no way of knowing which of the statements caused the exception (the ex.stacktrace shows our current method (doit), its caller, its caller's caller, etc. but neither do1 or do2):
function doit() {
try {
do1();
do2();
[...]
}
catch (Exception ex) {
// what failed?
}
}
generally I've taken to wrapping all statements and rethrowing, sort of like:
private void do1() {
try {
// do whatever
} catch(Exception e) {
// write to my error log
throw new Exception("do1: " + e.Message, e.InnerException);
}
}
which leaves a trail of breadcrumbs in my log and makes the chain available for the upstream. The problem, of course, is that I have to wrap every method I write with this kind of code.
something tells me I'm being dumb about it. what is the right approach?
Ok, this is hard to get right because exception handling is a really really touchy subject and in the past people have fought religious wars over how to do this right.
First off: neither use an empty catch (try { ... } catch { ... }), nor catch(Exception ex).
The sole purpose of Exception-derived classes is to give you rich information about the kind of exception which occured so you can do something meaningful in your exception handler (if a thread crashed restart it, if a db connection failed non-permanently try again, then fail, etc).
People tend to use a catch-all handler for the outermost part of their code to log uncaught exceptions and this is kind of OK, but in any case you should either prompt the user or rethrow the exception (using throw, not throw ex - there is a ton of discussion about this as well).
Basically you do not programmatically care about where the Exception occured at all.
You can either handle it or you can't. If you can't handle it then you don't catch it.
Addendum: The most important reason for this "if you can do something about it, do so, otherwise dont you dare touch that exception" philosophy is that silently caught exceptions (whether logged or not) can lead to really hard-to-find bugs. Just pushing them out to a logfile might not be enough because in a live system you may not get the fully annotated stack trace (with line numbers and everything).
Addendum 2: Take for instance a textbox which expects an integer input. If the user supplies a string you cannot meaningfully process the input, maybe a conversion exception gets thrown, you catch that specific exception and reset the textbox to its old value and maybe inform the user about the erroneous input. Alternatively your program might either just die with an exception (bad design, you could recover from that exception) or silently go on showing the erroneous input, but still using the old value (bad design, the program is misleading).
If you are really sold on doing this (others have stated why this is bad already), use an Aspect Oriented Programming approach. This will make your life significantly easier and reduce the amount of code you end up writing and maintaining.
Take a look at PostSharp, it gives you a framework that allows you to decorate methods, classes, or namespaces with attributes that will generate this boilerplate error handling for you.
#Branko nailed it in the comments: the exception's stack trace shows the point where the exception was thrown, not where it was caught.
+1 for #ChaosPandion's comment: this is a very, very, very bad idea.
try and catch seem to me to be probably the single worst designed modern programming mechanism. We no longer have the ability to handle errors as we go; we must fail the entire procedure if a single exception occurs, unless we do something horrifying like try every statement individually. There is no longer the option of recovering, only failing as gracefully as possible.
The best pattern for this I have found so far is to wrap every user event in a try/catch (using a method, not an explicit try every time). Ex:
public static class Defines
{
public static bool TryAction(Action pAction)
{
try { pAction(); return true; }
catch(Exception exception) { PostException(exception); return false; }
}
}
...
private void DoSomething(int pValue)
{
...
}
private void MyControl_MyEvent(object pSender, MyEventArgs pEventArgs)
{
Defines.TryAction(() => DoSomething(pEventArgs.Data));
}
Beyond that, just try to write exception-less code. Only use explicit trys when you are very likely to get an exception and want to do a little more than just fail gracefully.
All the time, to avoid any run time error, I use the Exception handler:
as the following:
try
{
//My code which may raise an error.
}
catch (Exception ee)
{
string message = ee.Message;
ShowMessage();
}
My question is:
Is this considered as a good practice or bad practice? (I use the same
lines all the time)
What about the performance issue every time declaring a string?
When using those lines with a method which return a value, the
returning must be after the catch?
That's bad code. Actually very bad.
As all you do with the error message is to assign it to a string that you never use, you are effectively just catching the exception and ignoring it. This is pretty much the worst thing that you can do with an exception, as the program will continue on as if nothing happened, likely with unusable or corrupted data.
When catching exceptions:
Use a more specific Exception type, for example SqlException or IOException, so that you only capture the exceptions that you intend to catch, and that you know how to handle.
When catching an exception, either really handle it, or rethrow it so that it can be handled at a different level.
You should handle known issues first to improve performance, such as null references, empty strings, etc.
Use exceptions for exceptional cases.
Declaring the string isn't a bad thing in there, but its not doing anything other than holding another reference.
You can safely return from a try block. But as Damokles states, you should also have another return else where.
The general structure of exception handling is the following:
try
{
//do struff here
}
catch (...)
{
//handle exception here
}
finally
{
//clean up here
}
There are a couple of things to note in your code that are not entirely right (they are terrible in fact :p):
Only catch exceptions you are ready to handle and do not handle those you are not. This means that you should only catch particular exceptions (FileNotFoundException, ArgumentOutOfRangeException, whatever) that you know can happen in exceptional cases (never use exception handling as a normal execution flow tool). Catching System.Exception is considered bad practice (unless it is for logging purposes and you throw; immeadiately afterwards) because this exception can be thrown by any darn thing, which with all probability you have not foreseen when writing your code and therefore have no clue on how to handle it correctly.
Depending on your situation you should consider using finally blocks in order to clean up whatever you can before exiting the method (be it because of normal execution flow, or an unhandled exception). Note that finally blocks will be (normally) always executed before exiting the method scope.
Do not swallow exceptions and the information they contain. You should consider logging it somewhere (myApplication.log file) and show the user a more friendly "we have aproblem" message. Otherwise the only information you will have when bugs crop up in production will be whatever you show the user. All the valuable information stored in the caught exception will be lost.
There is no need to add exception handler in all the functions. Add the exception handling at the main() which wraps all the functions. Only add exceptions handlers at place where you intend to do some specific exception handling operation to prevent the application from crash.
Return value can be added in the try block.
I assume you are doing this to IGNORE exceptions? In that case you can do it like this:
try
{
// code
}
catch {}
This will catch all exceptions and do nothing with them(ignore).
I would however not recommend doing that, because you will now never know why some functionality in your system is not working as expected because no errors are thrown. I would then recommend at the minimum at least LOG the exception so that you can troubleshoot problems later. A better approach would be to log the exception and re-throw it and then have friendly exception handling at the UI layer.
This is considered a bad practice as you basically ignore the exception. You don't even show it to the user!
It's even double bad, because it is also a bad practice to copy-paste the same lines all over your code.
Recommended usage is to either handle the exception, or do not touch it at all. As it's rather uncommon that the code knows how to handle an exception, the common case is to not catch it at all!
Of course, way up in your main loop, you'll have a try-catch, which will log the exception and/or report the exception to the user.
With respect to your second question: Yes, a return statement can be part of the catch block. But if you don't know what to return, you should not catch the exception!
You should only catch exceptions that you are expecting and know how to handle them. by catch (Exception) you are catching all kind of exceptions in a method is not a good practice.
You can catch all exceptions to just log them or restart you application on fail..
For example
try
{
//My code which may raise an error.
}
catch (FileNotFoundException)//you are expecting this exception
{
//handle file not found here.
}
catch (Exception ee)
{
string message = ee.Message;
Log(message);
throw;//rethrow the exception
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Sometimes I do this and I've seen others doing it too:
VB:
Try
DontWannaCatchIt()
Catch
End Try
C#:
try
{
DontWannaCatchIt();
}
catch {}
I know I should catch every important exception that I'm expecting and do something about it, but sometimes it's not important to - or am I doing something wrong?
Is this usage of the try block incorrect, and the requirement of at least one catch or finally block an indication of it?
Update:
Now I understand the reason for this, and it's that I should at least comment on the empty catch block so others understand why it's empty. I should also catch only the exceptions I'm expecting.
Luckily for me I'm coding in VB so I can write it in just one catch:
Catch ex As Exception When TypeOf ex Is IOException _
OrElse TypeOf ex Is ArgumentException _
OrElse TypeOf ex Is NotSupportedException _
OrElse TypeOf ex Is SecurityException _
OrElse TypeOf ex Is UnauthorizedAccessException
'I don't actually care.
End Try
If you don't want to catch it, why are you using try in the first place?
A try statement means that you believe something can go wrong, and the catch says that you can adequately handle that which goes wrong.
So in your estimation:
try
{
//Something that can go wrong
}
catch
{
//An empty catch means I can handle whatever goes wrong. If a meteorite hits the
//datacenter, I can handle it.
}
That catch swallows any exceptions that happen. Are you that confident in your code that you can handle anything that goes wrong gracefully?
The best thing to do (for both yours and your maintenance programmer's sanity) is to explicitly state that which you can handle gracefully:
try
{
//Something that could throw MeteoriteHitDatacenterException
}
catch (MeteoriteHitDatacenterException ex)
{
//Please log when you're just catching something. Especially if the catch statement has side effects. Trust me.
ErrorLog.Log(ex, "Just logging so that I have something to check later on if this happens.")
}
No, you should not catch every important exception. It is okay to catch and ignore exceptions you don't care about, like an I/O error if there's nothing you can do to correct it and you don't want to bother reporting it to the user.
But you need to let exceptions like StackOverflowException and OutOfMemoryException propagate. Or, more commonly, NullReferenceException. These exceptions are typically errors that you did not anticipate, cannot recover from, should not recover from, and should not be suppressed.
If you want to ignore an exception then it is good to explicitly write an empty catch block in the code for that particular exception. This makes it clear exactly what exceptions you're ignoring. Ignoring exceptions very correctly is an opt-in procedure, not an opt-out one. Having an "ignore all exceptions" feature which can then be overridden to not ignore specific types would be a very bad language feature.
How do you know what types of exceptions are important and should not be caught? What if there are exceptions you don't know about? How do you know you won't end up suppressing important errors you're not familiar with?
try
{
}
// I don't care about exceptions.
catch
{
}
// Okay, well, except for system errors like out of memory or stack overflow.
// I need to let those propagate.
catch (SystemException exception)
{
// Unless this is an I/O exception, which I don't care about.
if (exception is IOException)
{
// Ignore.
}
else
{
throw;
}
}
// Or lock recursion exceptions, whatever those are... Probably shouldn't hide those.
catch (LockRecursionException exception)
{
throw;
}
// Or, uh, what else? What am I missing?
catch (???)
{
}
No catch or finally is invalid. Empty catch or finally is valid. Empty catch means you don't care about exceptions, you just try to do something and it doesn't matter if it doesn't work, you just want to go on. Useful in cleanup functions for example.
Also if you haven't to do something about an error maybe you should specify what kind of exception the program has to ignore.
If you have to ignore every exception, I can't see why you can't use try/catch in this way.
It's usually a mistake. Exceptions signal, well, exceptional behavior; when an exception is thrown it should mean that something went wrong. So to continue normal program flow as if nothing went wrong is a way of hiding an error, a form of denial. Instead, think about how your code should handle the exceptional case, and write code to make that happen. An error that propagates because you've covered it up is much harder to debug than one that surfaces immediately.
It's not made easy for you to do because it's considered bad practice by the majority of developers.
What if someone later adds a method call to the body of DontWannaCatchIt() that does throw an exception worth catching, but it gets swallowed by your empty catch block? What if there are some exceptions that you actually would want to catch, but didn't realize it at the time?
If you absolutely must do this, try to be as specific as possible with the type of exception you're going to catch. If not, perhaps logging the exception is an option.
An error exists, has been thrown, and needs to go somewhere. Normal code flow has been aborted and the fan needs cleaned.
No catch block = indeterminate state. Where should the code go? What should it do?
An empty catch block = error handled by ignoring it.
Note: VBA has a vile "On Error Continue"...
The reason I've heard is that if your try fails for ANY reason, giving you control of the error response is highly preferable to giving the Framework control of it, i.e., yellow screen or error 500.
what if you write only code with try
try
{
int j =0;
5/j;
}
this would equivalent to write
int j =0;
5/j;
so writing try does not make any sense , it only increse your count of lines.
now if you write try with empty catch or finally , you are explicitley instructing runtime to behave differently.
so that' why i think empty try block is not possible.
Yes, it is incorrect. It's like goto: one per 100 KLoc is fine, but if you need many of these, you are doing it wrong.
Swallowing exceptions without any reactions is one of the worse things in error handling, and it should at least be explicit:
try
{
DontWannaCatchIt();
}
catch
{
// This exception is ignored based on Spec Ref. 7.2.a,
// the user gets a failure report from the actual results,
// and diagnostic details are available in the event log (as for every exception)
}
The further-away-look:
Error handling is an aspect: in some contexts, an error needs to be thrown and propagate up the call stack (e.g. you copy a file, copy fails).
Calling the same code in a different context might require the error to be tracked, but the operation to continue (e.g. Copying 100 files, with a log indicating which files failed).
Even in this case, an empty catch handler is wrong.
With most languages, there is no other direct implementation than to try+catch within the loop, and build the log in the catch handler. (You could build a mroe flexible mechanism, though: Have a per-call-thread handler that can either throw, or stow away the message. However, interaction with debugging tools suffers without direct language support.)
A sensible use case would be implementing a TryX() from a X(), but that would have to return the exception in question.
I have two methods, one called straight after another, which both throw the exact same 2 exceptions (IF an erroneous condition occurs, not stating that I'm getting exceptions).
For this, should I write seperate try and catch blocks with the one statement in each try block and catch both exceptions (Both of which I can handle as I checked MSDN class library reference and there is something I can do, eg, re-open SqlConnection or run a query and not a stored proc which does not exist). So code like this:
try
{
obj.Open();
}
catch (SqlException)
{
// Take action here.
}
catch (InvalidOperationException)
{
// Take action here.
}
And likewise for the other method I call straight after. This seems like a very messy way of coding. The other way is to code with the exception variable (that is ommited as I am using AOP to log the exception details, using a class-level attribute). Doing this, this could aid me in finding out which method caused an exception and then taking action accordingly. Is this the best approach or is there another best practise altogether?
I also assume that, as only these two methods are thrown, I do not need to catch Exception as that would be for an exception I cannot handle (causes way out of my control).
Thanks
You shouldn't catch an exception unless you can handle it in a sensible way and recover from the error. With that in mind, you should either choose not to catch these exceptions, or else you should catch them and do something useful and continue.
Assuming that you are trying to do the latter: handle the error and continue, does it really makes sense to do the same thing no matter which of the two statements fails? Assume you have this:
try {
f1();
f2();
} catch (FooException) {
// Recover from error and continue
}
f3();
In this case if f1() fails and you recover from the error, f2() will never be executed - it goes straight to f3(). Is that really what you want? Maybe it is sometimes... but not usually.
More likely, after the error from f1() you either want to quit completely with an error or to recover and then go on to execute f2(). If so then you would need two separate try/catch blocks.
If you're not interested in recovery but just logging the exceptions then the simplest way is to let them propagate and catch them at a higher level (but before your program crashes or becomes unusable) and log the message and stack trace. This ensures that you will log all exceptions and saves you having to insert try/catch and logging code in every method that could throw.
You're right that you shouldn't be catching Exception.
Generally you need as many catch clauses as you have different recovery approaches. If the recovery behavior is different for these two methods, I see nothing wrong with using a try/catch for each.
Especially consider whether you'd run the second method after successfully recovering the first. If so, you definitely don't want to put the second method in the same try block where it will be skipped by the exception.
You could create a method that accepts an Action parameter:
void trySomething(Action mightThrow)
{
try
{
mightThrow();
}
catch(SqlException)
{
}
catch(InvalidOperationException)
{
}
}
Then you can get the name of the method that threw by mightThrow.Method.Name.
I know you're not suppose to write code that caches all exception types like this.
try
{
//code that can throw an exception
}
catch
{
//what? I don't see no
}
Instead you're suppose to do something more like the code below allowing any other exception that you didn't expect to bubble up.
try
{
//code that can throw an exception
}
catch(TypeAException)
{
//TypeA specific code
}
catch(TypeBException)
{
//TypeB specific code
}
But is it ok to catch all exception types if you are wrapping them with another exception?
Consider this Save() method below I am writing as part of a Catalog class. Is there anything wrong with me catching all exception types and returning a single custom CatalogIOException with the original exception as the inner exception?
Basically I don't want any calling code to have to know anything about all the specific exceptions that could be thrown inside of the Save() method. They only need to know if they tried to save a read only catalog (CatalogReadOnlyException), the catalog could not be serialized (CatalogSerializationException), or if there was some problem writing to the file (CatalogIOException).
Is this a good or bad way to handle exceptions?
/// <summary>
/// Saves the catalog
/// </summary>
/// <exception cref="CatalogReadOnlyException"></exception>
/// <exception cref="CatalogIOException"></exception>
/// <exception cref="CatalogSerializingExeption"></exception>
public void Save()
{
if (!this.ReadOnly)
{
try
{
System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
this._catfileStream.SetLength(0); //clears the file stream
serializer.Serialize(this._catfileStream, this);
}
catch (InvalidOperationException exp)
{
throw new CatalogSerializationException("There was a problem serializing the catalog", exp);
}
catch (Exception exp)
{
throw new CatalogIOException("There was a problem accessing the catalog file", exp);
}
}
else
{
throw new CatalogReadOnlyException();
}
}
Update 1
Thanks for all the responses so far. It sounds like the consensus is I shouldn't be doing this, and I should only be catching exceptions if I actually have something to do with them. In the case of this Save() method there really isn't any exception that may be thrown that I want to handle in the Save() method itself. Mostly I just want to notify the user why they were not able to save.
I think my real problem is I'm using exceptions as a way to notify the user of problems, and I'm letting this inform how I am creating and handling exceptions a little too much. So instead should it sounds like it would be better to not catch any exceptions and let the UI layer figure out how to notify the user, and or crash. Is this correct? Consider the Save Menu event handler below.
private void saveCatalogToolStripMenuItem_Click(object sender, EventArgs e)
{
//Check if the catalog is read only
if (this.Catalog.ReadOnly)
{
MessageBox.Show("The currently opened catalog is readonly and can not be saved");
return;
}
//attempts to save
try
{
//Save method doesn't catch anything it can't deal with directly
this.Catalog.Save();
}
catch (System.IO.FileNotFoundException)
{
MessageBox.Show("The catalog file could not be found");
}
catch (InvalidOperationException exp)
{
MessageBox.Show("There was a problem serializing the catalog for saving: " + exp.Message);
}
catch (System.IO.IOException exp)
{
MessageBox.Show("There was a problem accessing the catalog file: " + exp.Message);
}
catch (Exception exp)
{
MessageBox.Show("There was a problem saving the catalog:" + exp.Message);
}
}
Update 2
One more thing. Would the answer change at all if the Save() method was part of a public API vs internal code? For example if it was part of a public API then I'd have to figure out and document all the possible exceptions that Save() may throw. This would be a lot easier if knew that Save() could only possibly throw one of my three custom exceptions.
Also if Save() was part of a public API wouldn't security also be a concern? Maybe I would want to let the consumer of the API know that the save wasn't successful, but I don't want expose anything about how Save() works by letting them get at the exceptions that may have been generated.
Doing a generic catch-all and rethrowing as a new type of exception does not really solve your problem and does not give you anything.
What you really need to do is to catch the exceptions that you can handle and then handle them (at the appropriate level - this is where rethrowing may be useful). All other exceptions either need to be logged so you can debug why they happened, or shouldn't be happening in the first place (for example - make sure you validate user input, etc.). If you catch all exceptions, you'll never really know why you're getting the exceptions you're getting and, thus, cannot fix them.
Updated Response
In response to the update of your question (particularly in how you want to handle the save case), my question to you would be - why are you using exceptions as a means of determine the path your program takes? For example, let's take the "FileNotFoundException." Obviously that can happen at times. But, instead of letting a problem happen and notifying the user about it, before saving (or doing whatever) with the file, why not check first that the file can be found. You still get the same effect, but you aren't using exceptions to control program flow.
I hope this all makes sense. Let me know if you have any additional questions.
When you re-throw with the original exception as inner exception, you lose the original stack trace, which is valuable debugging information.
I will sometimes do what you are suggesting, but I always log the original exception first to preserve the stack trace.
I don't see a problem with what you are doing. The reason for wrapping exceptions in a custom exception types is to create an abstraction between layers of code -- to translate lower-level errors into a higher-level context. Doing this relieves the calling code from having to know too much the implementation details of what Save does.
Your update #1 is an example of the calling code having to know way too much about the implementation details of Save(). In response to your second update, I agree 100%
PS
I'm not saying to do this in every scenario where you encounter exceptions. Only when the benefit outweighs the cost (usually at module boundaries).
Example scenarios for when this is especially useful: you are wrapping a 3rd party library, you don't yet know all the underlying exceptions that might be thrown, you don't have the source code or any documentation, and so on.
Also, he is wrapping the underlying exception and no information is lost. The exception can still be logged appropriately (though you'll need to recursion your way through the InnerExceptions).
I favor wrapping exceptions, from the standpoint that a custom exception hierarchy can divide exceptions into much more useful classifications than the default hierarchy. Suppose one tries to open a document and gets an ArgumentException or an InvalidOperationException. Does the type of the exception really contain any useful information whatsoever? Suppose, however, one instead got a CodecNotFoundException, a PrerenderFingFailureException, or a FontLoadFailureException. One can imagine the system catching some of those exceptions and attempting to do something about it (e.g. allow the user to search for a CODEC, retry rendering with lower-resolution settings, or allow substitution of fonts after warning the user). Much more useful than the default exceptions, many of which say nothing about what's really wrong or what can be done about it.
From a hierarchical standpoint, what's really needed is a means of distinguishing exceptions which indicate that the method throwing the exception was unable to perform its task, but the system state is similar to what it was before the method was started, and those which indicate that the system state is corrupt in a fashion beyond that implied by the method's failure. The normal exception hierarchy is completely useless for that; if one wraps exceptions one may be able to improve the situation slightly (though not as well as if the hierarchy were better designed to start with). An exception which forces a transaction to be unwound is not nearly as bad as one which occurs while committing or unwinding a transaction. In the former case, the state of the system is known; in the latter case, it isn't.
While one should probably avoid catching certain really bad exceptions (StackOverflowException, OutOfMemoryException, ThreadAbortException) I'm not sure it really matters. If the system is going to crash and burn, it's going to do so whether one catches the exception or not. In vb.net, it may be worthwhile to "Catch Ex As Exception When IsNotHorribleException(Ex)" but C# has no such construct, nor even a way to exclude certain exceptions from being caught.
Parting note: in some cases, one operation may generate multiple exceptions that are worthy of logging. Only by wrapping exceptions in a custom exception which holds a list of other exceptions can that really be accomplished.
I don't think its a good idea.
You should only add you own type of exception, if you have anything to add.
And furthermore, you should only catch exceptions that you expect, and that you are able to handle - all other exceptions should be allowed to bubble up.
As a developer I must say, I get angry if you try to "hide" exceptions from me, by swallowing or wrapping them.
For some more info on why catch(exception) is bad check out this article: http://blogs.msdn.com/clrteam/archive/2009/02/19/why-catch-exception-empty-catch-is-bad.aspx
Essentially catching 'Exception' is like saying 'if anything goes wrong I dont care carry on' and catching 'Exception' and wrapping it is like saying 'if anything goes wrong treat them as if they all went wrong for the exact same reason'.
This cannot be correct either you handle it because you semi-expected it or you totally don't think it should ever happen EVER (or didn't know it would). In this case you'd want some kind of app level logging to point you to an issue that you had never expected - not just a one size fits all solution.
My own rule of thumb is to catch and wrap Exception only if I have some useful context I can add, like the file name I was trying to access, or the connection string, etc. If an InvalidOperationException pops up in your UI with no other information attached, you're going to have a hell of a time tracking down the bug.
I catch specific exception types only if the context or message I want to add can be made more useful for that exception compared to what I would say for Exception generally.
Otherwise, I let the exception bubble up to another method that might have something useful to add. What I don't want to do is tie myself in knots trying to catch and declare and handle every possible exception type, especially since you never know when the runtime might throw a sneaky ThreadAbortException or OutOfMemoryException.
So, in your example, I would do something like this:
try
{
System.Xml.Serialization.XmlSerializer serializer =
new XmlSerializer(typeof(Catalog));
this._catfileStream.SetLength(0); //clears the file stream
serializer.Serialize(this._catfileStream, this);
}
// catch (InvalidOperationException exp)
// Don't catch this because I have nothing specific to add that
// I wouldn't also say for all exceptions.
catch (Exception exp)
{
throw new CatalogIOException(
string.Format("There was a problem accessing catalog file '{0}'. ({1})",
_catfileStream.Name, exp.Message), exp);
}
Consider adding the inner exception's message to your wrapper exception so that if a user just sends you a screenshot of the error dialog, you at least have all the messages, not just the top one; and if you can, write the whole ex.ToString() to a log file somewhere.
In this particular case exceptions should be rare enough that wrapping it shouldn't be a useful thing and will likely just get in the way of error handling down the line. There are plenty of examples within the .Net framework where a specific exception that I can handle is wrapped in a more general one and it makes it much more difficult (though not impossible) for me to handle the specific case.
I have written an article on this very topic before. In it I reiterate the importance of capturing as much data about the exception as is possible. Here's the URL to the article:
http://it.toolbox.com/blogs/paytonbyrd/improve-exception-handling-with-reflection-and-generics-8718
What benefit does the user get from being told "There was a problem serializing the catalog"? I suppose your problem domain might be an extraordinary case, but every group of users I've ever programmed for would respond the same way when reading that message: "The program blew up. Something about the catalog."
I don't mean to be condescending towards my users; I'm not. It's just that generally speaking my users have better things to do with their attention than squander it constructing a fine-grained mental model of what's going on inside my software. There have been times when my users have had to build that kind of an understanding in order to use a program I've written, and I can tell you that the experience was not salutary for them or for me.
I think your time would be much better spent on figuring out how to reliably log exceptions and relevant application state in a form that you can access when your users tell you that something broke than in coming up with an elaborate structure for producing error messages that people are unlikely to understand.
To answer this question, you need to understand why catching System.Exception is a bad idea, and understand your own motivations for doing what your propose.
It's a bad idea because it makes the statement that anything that could have gone wrong is okay, and that the application is in a good state to keep running afterwards. That's a very bold statement to make.
So the question is: Is what you are proposing equivalent to catching System.Exception? Does it give the consumer of your API any more knowledge to make a better judgement? Does it simply encourage them to catch YourWrappedException, which is then the moral equivalent of catching System.Exception, except for not triggering FXCop warnings?
In most cases, if you know there's a rule against doing something, and want to know if something similar is "okay", you should start with understanding the rationale for the original rule.
This is a standard practice in .NET and how exceptions should be handled, especially for exceptions that are recoverable from.
Edit: I really have no idea why I'm being downvoted perhaps I read more into the authors intent than everyone else. But the way I read the code the fact he is wrapping those exceptions into his custom exception implies that the consumer of this method is equiped to handle those exceptions and that it is a responsibility of the consumer to deal with the error processing.
Not a single person that DV'd actually left any form of actual dispute. I stand by my answer that this is perfectly acceptable because the consumer should be aware of the potential exceptions this could throw and be equipped to handle them which is shown by the explicit wrapping of the exception. This also preserves the original exception so the stack trace is available and underlying exception accessible.