c# Best practice of catching exceptions with try-catch? - c#

Lets say I need to run methodA and methodA will throw a FormatException.
If I write this block:
try
{
methodA();
}
catch (Exception ex)
{
methodB();
}
catch (FormatException ex)
{
methodC();
}
Will it ever run methodC, knowing that FormatException is also an Exception and therefor will go into the catchblock of methodB.
Or is it better to write it like this:
try
{
methodA();
}
catch (Exception ex)
{
if(ex is FormatException)
{
methodC();
} else
{
methodB();
}
}

No, it won't ever run methodC, but if you swap the order of your catch's it will:
try
{
methodA();
}
catch (FormatException ex)
{
methodC();
}
catch (Exception ex)
{
methodB();
}
To quote MSDN:
It is possible to use more than one specific catch clause in the same try-catch statement. In this case, the order of the catch clauses is important because the catch clauses are examined in order. Catch the more specific exceptions before the less specific ones. The compiler produces an error if you order your catch blocks so that a later block can never be reached.

The catch block are always executed according to specific exception.
All the Exceptions are derived from System.Exception class so it should be in the last of your catch blocks.
All other catch blocks should of a specific Exception class (FormatException in your case) that you presumed, could be invoked by your method.
Dave's Answer is a perfect example for it and also if Exceptions in your catch blocks have some hierarchical relation then better reorder them in a reverse hierarchical order.

Related

Which is better to catch all exceptions except given types: catch and rethrow or catch when?

If I wanted to catch all exceptions except for given types, and those specific types would be re-thrown to be caught in a higher context, would it be better to do:
try
{
//Code that might throw an exception
}
//Catch exceptions to be handled in this context
catch (Exception ex) when (!IsExcludedException(ex))
{
//Handle leftover exceptions
}
Or would it be better to do:
try
{
//Code that might throw an exception
}
catch (SpecificException)
{
throw;
}
//Catch exceptions to be handled in this context
catch (Exception ex)
{
//Handle leftover exceptions
}
Or does it not really matter? Is there a better way?
The second way is definitely cleaner to analyse and it's what I see the most. The specific catch happens first and doesn't trigger the generic one, but you still have a fallback if you didn't implement a specific one. Also, for handling more than one specific exception you'd need more !(ex is SpecificException) checks as well.

Reuse catch for all catches

is it possible to do something like the following:
I want to catch a custom exception and do something with it - easy: try {...} catch (CustomException) {...}
But then i want to run the code used in the "catch all" block still run some other code which is relevant to all catch blocks...
try
{
throw new CustomException("An exception.");
}
catch (CustomException ex)
{
// this runs for my custom exception
throw;
}
catch
{
// This runs for all exceptions - including those caught by the CustomException catch
}
or do i have to put whatever i want to do in all exception cases (finally is not an option because i want it only to run for the exceptions) into a separate method/nest the whole try/catch in another (euch)...?
I generally do something along the lines of
try
{
throw new CustomException("An exception.");
}
catch (Exception ex)
{
if (ex is CustomException)
{
// Do whatever
}
// Do whatever else
}
You need to use two try blocks:
try
{
try
{
throw new ArgumentException();
}
catch (ArgumentException ex)
{
Console.WriteLine("This is a custom exception");
throw;
}
}
catch (Exception e)
{
Console.WriteLine("This is for all exceptions, "+
"including those caught and re-thrown above");
}
Just do the overall catch and check to see if the exception is that type:
try
{
throw new CustomException("An exception.");
}
catch (Exception ex)
{
if (ex is CustomException)
{
// Custom handling
}
// Overall handling
}
Alternately, have a method for overall exception handling that both call:
try
{
throw new CustomException("An exception.");
}
catch (CustomException ex)
{
// Custom handling here
HandleGeneralException(ex);
}
catch (Exception ex)
{
HandleGeneralException(ex);
}
No, it doesn't do this way, you either catch a specific exception (linearly) or a generalisation. If you wish to run something for all exceptions you would need to keep a record of whether or not an exception has been thrown, perhaps what it was etc, and use finally, or another contrived, probably more 'messy' and verbose, mechanism.

Is there a reason to throw an exception twice?

Debugging production code I came across something I had not seen before and am not aware of a valid purpose. In several methods of one of our controllers we have try-catch blocks. The interesting part is there are 2 throw statements in one of the catches.
Is there any reason to have 2 throw statements? If so, in what circumstance(s) does that make sense?
try
{
//statements
}
catch (SoapException se)
{
//Log statement
return null;
}
catch (Exception ex)
{
//Log statement
throw;
throw;
}
No there is no reason to throw twice. The second throw will never be reached.
It is also similar to having
public int GetNumber()
{
return 1;
return 2; // Never reached
}
Update
Resharper is a great tool to check things like this.
In this case it will grey out the second throw and tell you it is unreachable.
In the example you showed, there would be no purpose to the two throw statements. As soon as the first one is hit it starts to work its way back up the call stack until it is caught. The only way for two to make any differance is if the first one was conditional or caught before he second one was hit.
try
{
//statements
}
catch (SoapException se)
{
//Log statement
return null;
}
catch (Exception ex)
{
//Log statement
if (condition)
throw;
throw;
}
or
try
{
//statements
}
catch (SoapException se)
{
//Log statement
return null;
}
catch (Exception ex)
{
//Log statement
try
{
throw;
}
catch (Exception)
{
//Handle first thrown exception.
}
throw;
}
There is absolutely no purpose in throwing an exception twice in a row. The second throw can never be reached, and it is most likely a typo, or code that was edited, but never completed and since forgotten about.

Execution of multiple catch blocks [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
executing multiple catch blocks
Can multiple catch blocks be executed for a single try statement?How can we handle the catch blocks?Can we create try without catch block??
There can be multiple catch blocks (as said in other answers already), but only the one that first matches the exception type is executed. That means you need to order the catch blocks properly. For example:
try
{
}
catch (Exception exp1)
{
// Block 1
}
catch (IOException exp2)
{
// Block 2
}
Block 2 will never be executed, as block 1 catches every exception (all exception classes are derived from Exception).
try
{
}
catch (IOException exp1)
{
// Block 1
}
catch (Exception exp2)
{
// Block 2
}
In this example, block 2 will only be executed if the exception is not an IOException or derived from IOException. If an IOException is thrown, only block 1 will execute, block 2 will not.
You can have multiple catch blocks associated with a try block,but only a single catch block can ever handle your exception.
Yes you can have a try block without a catch,but it is mandatory to have a
finally block
Technically you can only hit one catch BUT you say:
Can multiple catch blocks be EXECUTED for a single try statement
Keyword being executed. So, you could try:
catch (Exception ex)
{
if (ex is MyException1||
ex is MyException2)
{
//do stuff
}
else
{
throw;
}
}
Yes you can have multiple catch blocks with try statement. You start with catching specific exceptions and then in the last block you may catch base Exception. Only one of the catch block will handle your exception.
You can have try block without a catch block. try/finally will do.
try
{
Console.Write("test");
}
catch (IOException ex)
{
}
catch (ArithmeticException ex)
{
}
catch (Exception ex)
{
}
try without catch
try
{
}
finally
{
}
1 Yes it's possible to have multiple catch, one catch for one specific exception
Sample
try
{
...
}
catch (FormatException)
{
....
}
catch (OverflowException)
{
...
}
2 You can have try instrction without catch
try
{
...
}
Finally
{
.....
}
Only one catch block will execute, and it will be the catch that closely matches the type of the Exception that was thrown.
You can't have a try by it self. You need a try catch (one or more catch block) or a try finally or a try catch finally
You can have any number of catch block for a single try..catch statement.
But please remeber one thing, that your
catch (Exception ex)
{
...
}
Should be the last catch block, since all exceptions inherits the the class Exception.
As for the second part of your question, you can do either
try
{
stuff...
}
catch(Exception ex){}
or
try
{
stuff...
}
finally{}
, but you can't do try by itself.

C# try..catch - redirecting error handling flow from one catch to the next

I have a try..catch block that looks like this:
try
{
...
}
catch (IOException ioEx)
{
...
}
catch (Exception ex)
{
...
}
I'd like to handle just a certain kind of IOException, namely a sharing violation (Win32 0x20). Other IOExceptions and all other Exception descendants should be handled generally by the second catch-all catch.
Once I know that the IOException is not a sharing violation, how can I cleanly redirect the error handling flow to the general catch? If I rethrow in catch (IOException) the second catch does not invoke. I know I can nest try..catches but is there a cleaner way?
EDIT: On factoring-out handler logic
Factoring repeated code in methods will surely work, but I noticed that in general when you use factored methods for exception handling it tends to have subtle problems.
First of all, a catch clause has direct access to all of the local variables prior to the exception. But when you "outsource" exception handling to a different method then you have to pass the state to it. And when you change the code so does the handler method's signature changes, which might be a maintainability issue in more complicated scenarios.
The other problem is that program flow might be obscured. For example, if the handler method eventually rethrows the exception, the C# compiler and code analyzers like Resharper don't see it:
private void Foo()
{
string a = null;
try
{
a = Path.GetDirectoryName(a);
System.Diagnostics.Debug.Print(a);
}
catch (Exception ex)
{
HandleException(ex, a); //Note that we have to pass the "a"
System.Diagnostics.Debug.Print(
"We never get here and it's not obvious" +
"until you read and understand HandleException"
);
...!
}
}
static void HandleException(Exception ex, string a)
{
if (a != null)
System.Diagnostics.Debug.Print("[a] was not null");
throw (ex); //Rethrow so that the application-level handler catches and logs it
}
VS
private void Bar()
{
string a = null;
try
{
a = System.IO.Path.GetDirectoryName(a);
System.Diagnostics.Debug.Print(a);
}
catch (Exception ex)
{
if (a != null)
System.Diagnostics.Debug.Print("[a] was not null");
throw; //Rethrow so that the application-level handler catches and logs it
System.Diagnostics.Debug.Print(
"We never get here also, but now " +
"it's obvious and the compiler complains"
);
...!
}
}
If I want to avoid these kind of (minor) problems then it seems that there is no cleaner way than nesting try..catch blocks, as Hank pointed out.
Just factor the handling logic into a separate method.
try
{
...
}
catch (IOException ioEx)
{
if (sharing violation)
HandleSharingViolation();
else
HandleNonsharingViolation();
}
catch (Exception ex)
{
HandleNonsharingViolation();
}
Or test the exceptions yourself
catch (Exception ex)
{
if (ex is IOException && ex.IsSharingViolation()
HandleSharingViolation();
else
HandleNonsharingViolation();
}
No, you'll have to nest.
Once you are in 1 of the catch blocks, this 'try' is considered handled.
And I think it may make a lot of sense, "sharing violation" sounds like a special case that probably isn't so tightly coupled to the rest as you might be thinking. If you use nest try-catch, does the try block of the special case has to surround the exact same code? And of course it's a candidate to refactor out as a separate method.
Create Method to handle exception, pass the exception to that method , based on the type Handle the exception in the way you want.Call these method in both these blocks.
Use nested try catch blocks.
try
{
try
{
}
catch (IOException ioEx)
{
if (....)
else
throw;
}
}
catch
{
}
what about "finally"?
you can first set a 'variable' in the IOException block once you know the IOException is not sharing violation. Then, in your finally block, if that 'variable' is set, you proceed to do whatever you need to do.
Below impl. tested and confirmed.
bool booleanValue = false;
try
{
test1(); // this would thro IOException
}
catch (IOException e)
{
booleanValue = true; // whatever you need to do next
}
finally
{
if (booleanValue)
{
Console.WriteLine("Here");
}
}
Tryout this nested block
try
{
}
catch(Exception ioex)
{
try
{
}
catch(Exception ex)
{
}
}

Categories

Resources