To throw or not to throw an exception in C# [duplicate] - c#

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why catch and rethrow Exception in C#?
I've been scouring the net trying to find the answer to this question - What's the between the two?
try
{
//Do Something
}
catch
{
throw;
}
vs
try
{
//Do Something
}
catch
{
}
or
try
{
//Do Something
}
catch (Exception Ex)
{
//Do something with Exception Ex
}

The first one rethrows the exception up the stack and preserves the stack trace.
The second one swallows (hides) the exception.
The third one probably also swallows the exception but it depends on what (//Do something) does.

catch --> throw will actually just throw your error, so you will have to catch it somewhere else. This can be useful if you want to catch something first and then throw the error to other methods above.
Example:
try
{
// do something
}
catch
{
Console.WriteLine("Something went wrong, and you'll know it");
throw;
}
// won't get here anymore, the exception was thrown.
While try --> catch will just let you ignore the error.
try
{
// do something
}
catch
{
Console.WriteLine("Something went wrong, and you won't know it.");
}
// continuing happily

The first one re-throws the same exception that was caught. the second one swallows the exception as if it never happened. So it depends on what you need.
Please note that there IS a difference between these two:
try
{
//Do Something
}
catch (Exception Ex)
{
//re-throws the same exception that was caught
throw;
}
try
{
//Do Something
}
catch (Exception Ex)
{
//throws a _new_ exception containing Ex
throw Ex;
}

In the first, you are just rethrowing the exception. You don't need try/catch in this case, because you aren't doing anything with the caught exception.
In the second, you are swallowing all exceptions. This is incredibly dangerous. Do not ever do this. It is never correct.
In the last, you haven't given us enough detail to know. You are catching the exception, and you might do something with it. You could rethrow, you could swallow. You haven't told us.

In the first block, an exception is thrown again inside of the handler for the first block. That means that it can be picked up by an outer-try/catch scope block. The second block "eats" the exception in the catch block, and program execution can continue normally after the code in the catch block is executed.

In the first case the exception is rethrown to the caller. This version is pointless because you do nothing with the exception but in practice you may do something and then throw the exception to the caller. It is also useful when filtering exceptions for example
try
{
//do somethign
}
catch(Exception1)
{
throw;
}
catch
{
//do something
}
The second is something you should never do. You are covering an exception and making it harder to catch eventual bug in your application. You either need to handle the exception in a meaningful way or let it break the program (or let the caller handle it)
The third example is simple exception handing. Make sure you don't use it as a form of if/else (flow control)

Related

Exceptions to Never Catch

I know that there are some exception types that cannot be caught in catch blocks, like StackOverflowException in .NET 2.0. I would like to know which other exceptions are inadvisable to catch, or are associated with bad practices.
The way I would like to use this list of exception types is to check it every time I am using Exception in a catch block:
private static readonly Type[] _exceptionsToNotCatch = new Type[] { typeof(StackOverflowException) };
// This should never throw, but should not swallow exceptions that should never be handled.
public void TryPerformOperation()
{
try
{
this.SomeMethodThatMightThrow();
}
catch (Exception ex)
{
if (_exceptionsToNotCatch.Contains(ex.GetType()))
throw;
}
}
EDIT
I don't think I provided a very good example. That's one of the problems with trying to make an example trivial when trying to communicate one's meaning.
I never throw Exception myself, and I always catch specific exceptions, only catching Exception as follows:
try
{
this.SomeMethodThatMightThrow();
}
catch (SomeException ex)
{
// This is safe to ignore.
}
catch (Exception ex)
{
// Could be some kind of system or framework exception, so don't handle.
throw;
}
My question was meant as more of an academic one. What exceptions are only thrown by the system and should never be caught? I am worried about situations more like this:
try
{
this.SomeMethodThatMightThrow();
}
catch (OutOfMemoryException ex)
{
// I would be crazy to handle this!
// What other exceptions should never be handled?
}
catch (Exception ex)
{
// Could be some kind of system or framework exception, so don't handle.
throw;
}
This question was really inspired by the following:
System.Data.EntityUtil.IsCatchableExceptionType(Exception) in System.Data.Entity, Version=3.5.0.0
I would like to know which other exceptions are inadvisable to catch, or are associated with bad practices.
Here is the list of all exceptions you shouldn't catch:
Any exception you don't know what to do with
Here's the best practice for exception handling:
If you don't know what to do with an exception, don't catch it.
This may sound snarky, but they're both correct, and that's all you need to know.
It's generally not a good idea to do that.
You should catch the most specific exception(s) possible and only carry on execution of your program when it is safe to do so. E.g. if you're opening a file, it's perfectly reasonable to catch exceptions relating to file access / permission errors, but probably not much else. You certainly wouldn't want to catch an OutOfMemoryException and then blindly carry on. They're very different errors!
If you apply a blanket rule of what to catch, there's no guarantee that your program will be able to continue execution safely because you're not responding to specific situations, just applying a one size does not fit all solution.
Using Exception in the catch block would catch all exceptions that are catchable. I would say you should specify only exceptions that needs to be caught and let the ones you don't want to catch spill out. E.g.
try
{
}
catch(SqlException sqlex) //specific to database calls
{
//do something with ex
}
catch(FormatException fex) //specific to invalid conversion to date, int, etc
{
//do something with ex
}
catch(Exception ex)
{
//I didn't know this exception would be thrown
//log it for me or Rethrow it
}
Any other exception not in that list will not be caught
Okay so we've established it ain't a good idea. And we've established that programmers on SO prefer to opine from their high-horses rather than hand you a knife to stab yourself with, so for those with suicidal tendencies, let's start with these:
(Redacted my list and DRYing-up SO to point to Hans' list)
https://stackoverflow.com/a/5508733/17034

This exception handling code requires fixing

This is my current exception handling code.
Take especial note of the line throw e; marked with ***.
try
{
//some code that could cause exception
}
catch (FaultException e) //first catch a particular type of exception only
{
if (Regex.IsMatch(e.Message, "something")) //satisfying a particular condition
{
Console.WriteLine("Particular exception occurred.");
return;
}
else
throw e; // <-- *** Problem! Not getting caught by the "catch" below.
}
catch (Exception e) //catch all other exceptions
{
Console.WriteLine("General exception ocurred");
return;
}
The problem is this: If the throw e; // <-- *** occurs, it is not getting caught by the final catch. Instead, the app just crashes as if the exception was not handled.
How can this be fixed in the simplest possible way?
You see in the first catch that I'm only interested in actually handling FaultException exceptions satisfying a particular condition, but leave all others (both FaultException exceptions not satisfying the condition and exceptions that are not FaultException) to the final catch. Unfortunately, this is not working properly.
I'm on .NET 4.
You don't fully understand the try/catch syntax. You can attach multiple catches to a single try - the one that matches most closely is the one that will be selected. In this case, FaultException's catch will fire, and then the more general Exception one will never be called, because the exception has already been handled.
What you need to do is wrap the entire try/catch in another try/catch specifically for the more general Exception case, if you always want to handle that; either that or rework your logic. (For instance, you could just simplify it to be an Exception catch and then check if it's a FaultException.)
Only one catch block is executed per try block.
I would rewrite the catch block as:
catch (Exception e)
{
if (e is FaultException && Regex.IsMatch(e.Message, "something"))
{
....
}
else // all other exceptions
{
....
}
}
The throw e will never be caught by exception catches at the same level.
A throw inside of a catch, will always throw to the invoker of the method.
Also, its recommended that if you want to re-throw do throw instead of throw e. The first case preserves the call-stack.
If you throw an exception within a catch block, it won't be caught within the same try-catch.
You could repeat in the else condition what you're doing in the other catch block (not too bad in this specific case).

Reading exception from try catch when exception type not specified

In cases when you use a try catch block as such.
try {
//Do my work!
}
catch
{
//Handle my exception
}
Is there some way to refer to the exception object in the catch block?
ie:
try {
//Do my work!
}
catch
{
//Handle my exception
MyUndefinedExceptionObject.Message ????
}
EDIT: I don't think I was clear
enough. I am aware of how one would
typically catch exceptions using a try
catch block. What I am wondering is
given you have the ability to not
specify a type for your exception yet
declare the block is there still some
way of retrieving the exception object
in such cases? Judging by your answers
however I assume there isn't?
You'll want to catch the exception type you care about. When you do, you'll have access to all the properties of that exception.
try
{
//Do my work!
}
catch (MyExceptionType e)
{
string s = e.Message;
}
Here's a reference in MSDN, to get up to speed.
Regarding your edit: no there is no way to access the thrown exception unless the exception is explicitly specified in your catch statement.
Yes, like this:
try
{
//Do my work!
}
catch (mySpecificException myEx)
{
//Handle my exception
}
catch (Exception ex)
{
//Handle my exception
}
(Most specific to least specific)
No.
Using the bare catch indicates that you do not care about the actual exception otherwise, why not use
catch (System.Exception ex)
to catch any exception? Of course, you should only catch exceptions you will handle.
You need to indicate the specific type of exception that you are catching, and assign that to a variable.
Do that using this syntax instead:
try
{
// Do work
}
catch (MyUndefinedExceptionObject ex)
{
Debug.WriteLine(ex.Message);
}
You can also include multiple catch blocks with the type of exception altered accordingly. However, remember that you should always order them from most derived to least derived, ending with the base class for all exceptions, System.Exception.
You also should generally refrain from catching System.Exception, instead preferring only to catch the derived exceptions that you can handle in the catch block and that won't corrupt your program's state. Catching System.Exception class is a bad idea because you'll also catch exceptions that you won't be able to handle, like an OutOfMemoryException or a StackOverflowException.
Microsoft has a helpful article on best practices here: Best Practices for Handling Exceptions

What does "throw;" by itself do? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
difference between throw and throw new Exception()
What would be the point of just having
catch (Exception)
{
throw;
}
What does this do?
By itself, the throw keyword simply re-raises the exception caught by the catch statement above. This is handy if you want to do some rudimentary exception handling (perhaps a compensating action like rolling back a transaction) and then rethrow the exception to the calling method.
This method has one significant advantage over catching the exception in a variable and throwing that instance: It preserves the original call stack. If you catch (Exception ex) and then throw ex, your call stack will only start at that throw statement and you lose the method/line of the original error.
Sometimes you might want to do something like this:
try
{
// do some stuff that could cause SomeCustomException to happen, as
// well as other exceptions
}
catch (SomeCustomException)
{
// this is here so we don't double wrap the exception, since
// we know the exception is already SomeCustomException
throw;
}
catch (Exception e)
{
// we got some other exception, but we want all exceptions
// thrown from this method to be SomeCustomException, so we wrap
// it
throw new SomeCustomException("An error occurred saving the widget", e);
}
It rethrows the exact same error, you gain nothing by this.
Sometimes you can use the catch method to do some logging or something without interupting your exception like this:
catch (Exception) {
myLogger.Log(LogLevels.Exception, "oh noes!")
throw;
}
I initially mistakingly thought this would unwind your stack, but this would only be if you would do the following:
catch (Exception err) {
throw err;
}
Only reason I can think of is if you want to put a breakpoint there during debugging.
It's also the default code being generated by some tools I think.
Simply rethrow the current exception, and that exception will keep its "source" and the stack trace.

Thoughts on try-catch blocks

What are your thoughts on code that looks like this:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
throw;
}
}
The problem I see is the actual error is not handled, just throwing the exception in a different place. I find it more difficult to debug because i don't get a line number where the actual problem is.
So my question is why would this be good?
---- EDIT ----
From the answers it looks like most people are saying it's pointless to do this with no custom or specific exceptions being caught. That's what i wanted comments on, when no specific exception is being caught. I can see the point of actually doing something with a caught exception, just not the way this code is.
Depending on what quality you are looking at it is not throwing the exception in a different place. "throw" without a target rethrows the exception which is very different from throwing an exception. Primarily a rethrow does not reset the stack trace.
In this particular sample, the catch is pointless because it doesn't do anything. The exception is happily rethrown and it's almost as if the try/catch didn't exist.
I think the construction should be used for handling the exceptions you know you will be throwing inside your code; if other exception is raised, then just rethrow.
Take into account that
throw;
is different than
throw ex;
throw ex will truncate the stack to the new point of throwing, losing valuable info about the exception.
public void doSomething()
{
try
{
// actual code goes here
}
catch (EspecificException ex)
{
HandleException(ex);
}
catch (Exception ex)
{
throw;
}
}
It wouldn't be, ideally the catch block would do some handling, and then rethrow, e.g.,
try
{
//do something
}
catch (Exception ex)
{
DoSomething(ex); //handle the exception
throw;
}
Of course the re-throw will be useful if you want to do some further handling in the upper tiers of the code.
Doing something like that is fairly meaningless, and in general I try not to go down the road of doing meaningless things ;)
For the most part, I believe in catching specific types of exceptions that you know how to handle, even if that only means creating your own exception with more information and using the caught exception as the InnerException.
Sometimes this is appropriate - when you're going to handle the exception higher up in the call stack. However, you'd need to do something in that catch block other than just re-throw for it to make sense, e.g. log the error:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
LogException (ex); // Log error...
throw;
}
}
I don't think just rethrowing the error would be useful. Unless you don't really care about the error in the first place.
I think it would be better to actually do something in the catch.
You can check the MSDN Exception Handling Guide.
I've seen instances where generic exceptions are caught like this and then re-packed in a custom Exception Object.
The difference between that and what you're saying is that those custom Exception objects hold MORE information about the actual exception that happened, not less.
Well for starters I'd simply do
catch
{
throw;
}
but basically if you were trapping multiple types of exceptions you may want to handle some locally and others back up the stack.
e.g.
catch(SQLException sex) //haha
{
DoStuff(sex);
}
catch
{
throw;
}
Depends on what you mean by "looks like this", and if there is nothing else in the catch block but a rethrow... if that's the case the try catch is pointless, except, as you say, to obfuscate where the exception occurred. But if you need to do something right there, where the error occurred, but wish to handle the exception furthur up the stack, this might be appropriate. But then, the catch would be for the specific exception you are handl;ing, not for any Exception
Generally having exception handling blocks that don't do anything isn't good at all, for the simple reason that it prevents the .Net Virtual Machine from inlining your methods when performance optimising your code.
For a full article on why see "Release IS NOT Debug: 64bit Optimizations and C# Method Inlining in Release Build Call Stacks" by Scott Hanselman

Categories

Resources