This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Are nested Try/Catch blocks a bad idea?
Currently I am using try catch within try catch ? The current senario requires it in our application.
void MyFun()
{
try
{
//Process logic 1
// ......
try
{
//Process logic 2
// ......
} catch (Exception ex)
{
//write an error details in database
}
//Process Logic 3
// ......
} catch (Exception ex)
{
//show error msg
}
}
No particular problem with this especially if you want to handle the exceptions differently.
However, if the inner exception and the outer exception are of different types E1, E2 respectively and E1 is not a parent of E2, you can have two adjacent catch clauses.
try
{
// do something
}
catch (E1 e1)
{
}
catch (E2 e2)
{
}
As noted by Rob and J.Steen - this is slightly different than the case in the question as in this case is E1 is thrown the code after it will not be executed.
A nested try/catch is fine. what you want to stay away from is changing the logical flow of your code based on the try catch. In other words, you shouldn't treat a try/catch as an if/else block. so this isn't ideal:
//over the top example just to demonstrate my point
public bool IsNumberTen(int x)
{
try
{
if(x > 10)
throw new NumberTooHighException();
else if(x < 10)
throw new NumberTooLowException();
else
return true;
}
catch(NumberTooHighException)
{
return false;
}
catch(NumberTooLowException)
{
return false;
}
}
This item suggests that its not a bad thing and that you would only have to handle the error in another way any way.
Exception handling try catch inside catch
I don't see why not. If you have logic in the catch which may fail or raise an exception that requires handling then it makes sense.
Its a little difficult to answer this question without knowing what logic is in here.
Certainly in terms of performance, nested exception handling will incur a greater cost, but general rule of thumb is only catch exceptions that you as a developer understand how to handle. This overlaps into the practice of TDD where if you have a good enough set of tests you can identify where the expected exceptions should be, then this will dictate your exception logic.
I would say this: it's not bad. Whether it's good depends on your program, and whether such a concept makes sense given your method's logic and contracts.
Edit: I'd suggest checking out the article Exception Cost: When to throw and when not to. It outlines what is most expensive for exception management in the CLR.
I am trying to think of situations where you may want a nested block... perhaps if you are making database changes and you are using the try catch as a virtual transaction, you may want to try to update some properties but then carry on if that fails, but also catch an overall exception if and when you actually commit to the database update itself.
Even with this considered, you should never need to do this... It should be perfectly sufficient to simply stack blocks next to each other like so:
void MyFun()
{
try
{
//Process logic 1
// ......
} catch (Exception ex)
{
//show error msg
}
try
{
//Process logic 2
// ......
} catch (Exception ex)
{
//write an error details in database
}
}
It is also probably worth noting that if you find the need to nest try catch blocks then there is probably a better way you could be designing your code.
EDIT: Itay's answer is also somewhat better than nesting, although it will not allow you to carry on in the block once you have caught an exception.
Hope this helps!
Related
This question already has answers here:
Is it "bad" to use try-catch for flow control in .NET?
(8 answers)
Closed 8 years ago.
I have 2 pieces of code. What would say is best practice and why?
In the first version I add a new shop and evaluate if it's successful with Exceptions, and in the second version I do the same with "if" statements.
I've recently read that Exceptions can be expensive in the code, and if all "Add" method is implemented this way it can cause performance issues.
Can anybody confirm this?
Thanks!!!
public bool AddShop1(Shop newShop)
{
try
{
ShopDictionary.Add(newShop.ShopId, newShop);
return true;
}
catch (ArgumentNullException)
{
return false;
}
catch (ArgumentException)
{
return false;
}
}
public bool AddShop2(Shop newShop)
{
if (newShop == null || ShopDictionary.ContainsKey(newShop.ShopId))
{
return false;
}
ShopDictionary.Add(newShop.ShopId, newShop);
return true;
}
you should not use try catch for the control flow logic.
that should be done using if or switches etc.
try catch should be used for uncertain situations only, and should then be handled accordingly.
It depends from how often your function will cause exception. If exceptions will happen rarely (once per 1000 calls), then you can ignore slowdown of performance. But if from 1000 executions you'll get 800 exceptions, then definitely convert to ifs. But then just a question, if from 1000 you have 800 exceptions, is it really exception, or a rule of business logic?
Well, avoiding exception is more preferred for the performance for your application. and if you really interested in exception, you can do like this way,
public bool AddShop2(Shop newShop, out Exception exception)
{
exception = null;
try
{
if (newShop == null || ShopDictionary.ContainsKey(newShop.ShopId))
{
return false;
}
ShopDictionary.Add(newShop.ShopId, newShop);
}
catch (Exception ex)
{
exception = ex;
}
return true;
}
I have a question that might seem fairly simple (of course if you know the answer).
A certain function I have calls another function but I want to continue execution from the caller even though the callee has thrown an exception. Let me give you an example:
something function1()
{
try
{
//some code
int idNumber = function2();
//other code that need to execute even if function2 fails
return something;
}
catch(Exception e)
{//... perhaps something here}
}
EDIT: function1 also has a return statement so nothing can in fact crash on the way
In function2 I need to do stuff but I only need to log if anything fails, example:
int function2()
{
try
{
//dostuff
}
catch(Exception e)
{
//Log stuff to db
}
}
ok, now my question is, what should I do if I wanted to continue execution in function1 even if function 2 throws an error?
Sometimes I mix up if I should do throw; or throw e; or throw nothing at all (leave catch block empty)
Leaving the catch block empty should do the trick. This is almost always a bad idea, though. On one hand, there's a performance penalty, and on the other (and this is more important), you always want to know when there's an error.
I would guess that the "callee" function failing, in your case, is actually not necessarily an "error," so to speak. That is, it is expected for it to fail sometimes. If this is the case, there is almost always a better way to handle it than using exceptions.
There are, if you'll pardon the pun, exceptions to the "rule", though. For example, if function2 were to call a web service whose results aren't really necessary for your page, this kind of pattern might be ok. Although, in almost 100% of cases, you should at least be logging it somewhere. In this scenario I'd log it in a finally block and report whether or not the service returned. Remember that data like that which may not be valuable to you now can become valuable later!
Last edit (probably):
In a comment I suggested you put the try/catch inside function2. Just thought I would elaborate. Function2 would look like this:
public Something? function2()
{
try
{
//all of your function goes here
return anActualObjectOfTypeSomething;
}
catch(Exception ex)
{
//logging goes here
return null;
}
}
That way, since you use a nullable return type, returning null doesn't hurt you.
Why cant you use the finally block?
Like
try {
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK
} finally {
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
EDIT after question amended:
You can do:
int? returnFromFunction2 = null;
try {
returnFromFunction2 = function2();
return returnFromFunction2.value;
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK
} finally {
if (returnFromFunction2.HasValue) { // do something with value }
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
Or you can encapsulate the looping logic itself in a try catch e.g.
for(int i = function2(); i < 100 /*where 100 is the end or another function call to get the end*/; i = function2()){
try{
//ToDo
}
catch { continue; }
}
Or...
try{
for(int i = function2(); ; ;) {
try { i = function2(); return; }
finally { /*decide to break or not :P*/continue; } }
} catch { /*failed on first try*/ } finally{ /*afterwardz*/ }
just do this
try
{
//some code
try
{
int idNumber = function2();
}
finally
{
do stuff here....
}
}
catch(Exception e)
{//... perhaps something here}
For all intents and purposes the finally block will always execute. Now there are a couple of exceptions where it won't actually execute: task killing the program, and there is a fast fail security exception which kills the application instantly. Other than that, an exception will be thrown in function 2, the finally block will execute the needed code and then catch the exception in the outer catch block.
Do you mean you want to execute code in function1 regardless of whether function2 threw an exception or not? Have you looked at the finally-block? http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
In your second function remove the e variable in the catch block then add throw.
This will carry over the generated exception the the final function and output it.
Its very common when you dont want your business logic code to throw exception but your UI.
Is it possible to call catch for a special condition when you are inside of try without using system error? For instance if a value int value 1 and then I want to use "catch".
One of the biggest sins in programming:) Don't use exceptions for managing programming flow! Now to your question - the catch block can be called in case an exception is thrown.
Your wording is a bit confusing but I think this is what you want.
int value = GetValue();
try
{
if (value == 1)
throw new InvalidOperationException();
HappyPath(value);
}
catch (InvalidOperationException)
{
SadPath(value);
}
Incidentally using exceptions for control flow is not the best practice.
No. You should catch exceptions (you can filter them by type), and then inside catch block you can filter on any condition.
It is not possible in C# to throw an exception that doesn’t derive from Exception, even though the CLR allows it.
It is possible to catch such an exception, but it is not possible to access the object that was thrown:
try
{
MethodThatThrows();
}
catch // This catches everything, even objects not deriving from Exception
{
// Process exception
}
As soon as you specify a variable (e.g. catch (Exception e)), C# requires that the type is Exception or derived from it.
I think you might be saying that you want to catch an exception only in specific circumstances, and pass it through in all other circumstances? In that case, you can just use an if to check for the condition and then throw to re-throw the exception:
try
{
// ...
}
catch (Exception e)
{
// If it’s any value other than 1, we’re not interested in the exception
if (value != 1)
throw; // note: throw; *not* throw e;
// Process the exception here
}
Situation:
My application need to process the first step in the business rules (the initial try-catch statement). If an certain error occurs when the process calls the helper method during the step, I need to switch to a second process in the catch statement. The back up process uses the same helper method. If an same error occurs during the second process, I need to stop the entire process and throw the exception.
Implementation:
I was going to insert another try-catch statement into the catch statement of the first try-catch statement.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
HelperMethod(s1);
}
catch(Exception e1)
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
//try catch statement for second process.
try
{
HelperMethod(s2);
}
catch(Exception e2)
{
throw e2;
}
}
What would be the correct design pattern to avoid code smells in this implementation?
I caused some confusion and left out that when the first process fails and switches to the second process, it will send different information to the helper method. I have updated the scenario to reflect the entire process.
If the HelperMethod needs a second try, there is nothing directly wrong with this, but your code in the catch tries to do way too much, and it destroys the stacktrace from e2.
You only need:
try
{
//call helper method
HelperMethod();
}
catch(Exception e1)
{
// maybe log e1, it is getting lost here
HelperMethod();
}
I wouldn't say it is bad, although I'd almost certainly refactor the second block of code into a second method, so keep it comprehensible. And probably catch something more specific than Exception. A second try is sometimes necessary, especially for things like Dispose() implementations that might themselves throw (WCF, I'm looking at you).
The general idea putting a try-catch inside the catch of a parent try-catch doesn't seem like a code-smell to me. I can think of other legitimate reasons for doing this - for instance, when cleaning up an operation that failed where you do not want to ever throw another error (such as if the clean-up operation also fails). Your implementation, however, raises two questions for me: 1) Wim's comment, and 2) do you really want to entirely disregard why the operation originally failed (the e1 Exception)? Whether the second process succeeds or fails, your code does nothing with the original exception.
Generally speaking, this isn't a problem, and it isn't a code smell that I know of.
With that said, you may want to look at handling the error within your first helper method instead of just throwing it (and, thus, handling the call to the second helper method in there). That's only if it makes sense, but it is a possible change.
Yes, a more general pattern is have the basic method include an overload that accepts an int attempt parameter, and then conditionally call itself recursively.
private void MyMethod (parameterList)
{ MyMethod(ParameterList, 0)l }
private void MyMethod(ParameterList, int attempt)
{
try { HelperMethod(); }
catch(SomeSpecificException)
{
if (attempt < MAXATTEMPTS)
MyMethod(ParameterList, ++attempt);
else throw;
}
}
It shouldn't be that bad. Just document clearly why you're doing it, and most DEFINITELY try catching a more specific Exception type.
If you need some retry mechanism, which it looks like, you may want to explore different techniques, looping with delays etc.
It would be a little clearer if you called a different function in the catch so that a reader doesn't think you're just retrying the same function, as is, over again. If there's state happening that's not being shown in your example, you should document it carefully, at a minimum.
You also shouldn't throw e2; like that: you should simply throw; if you're going to work with the exception you caught at all. If not, you shouldn't try/catch.
Where you do not reference e1, you should simply catch (Exception) or better still catch (YourSpecificException)
If you're doing this to try and recover from some sort of transient error, then you need to be careful about how you implement this.
For example, in an environment where you're using SQL Server Mirroring, it's possible that the server you're connected to may stop being the master mid-connection.
In that scenario, it may be valid for your application to try and reconnect, and re-execute any statements on the new master - rather than sending an error back to the caller immediately.
You need to be careful to ensure that the methods you're calling don't have their own automatic retry mechanism, and that your callers are aware there is an automatic retry built into your method. Failing to ensure this can result in scenarios where you cause a flood of retry attempts, overloading shared resources (such as Database servers).
You should also ensure you're catching exceptions specific to the transient error you're trying to retry. So, in the example I gave, SqlException, and then examining to see if the error was that the SQL connection failed because the host was no longer the master.
If you need to retry more than once, consider placing an 'automatic backoff' retry delay - the first failure is retried immediately, the second after a delay of (say) 1 second, then doubled up to a maximum of (say) 90 seconds. This should help prevent overloading resources.
I would also suggest restructuring your method so that you don't have an inner-try/catch.
For example:
bool helper_success = false;
bool automatic_retry = false;
//run initial process
try
{
//call helper method
HelperMethod();
helper_success = true;
}
catch(Exception e)
{
// check if e is a transient exception. If so, set automatic_retry = true
}
if (automatic_retry)
{ //try catch statement for second process.
try
{
HelperMethod();
}
catch(Exception e)
{
throw;
}
}
Here's another pattern:
// set up state for first attempt
if(!HelperMethod(false)) {
// set up state for second attempt
HelperMethod(true);
// no need to try catch since you're just throwing anyway
}
Here, HelperMethod is
bool HelperMethod(bool throwOnFailure)
and the return value indicates whether or not success occurred (i.e., false indicates failure and true indicates success). You could also do:
// could wrap in try/catch
HelperMethod(2, stateChanger);
where HelperMethod is
void HelperMethod(int numberOfTries, StateChanger[] stateChanger)
where numberOfTries indicates the number of times to try before throwing an exception and StateChanger[] is an array of delegates that will change the state for you between calls (i.e., stateChanger[0] is called before the first attempt, stateChanger[1] is called before the second attempt, etc.)
This last option indicates that you might have a smelly setup though. It looks like the class that is encapsulating this process is responsible for both keeping track of state (which employee to look up) as well as looking up the employee (HelperMethod). By SRP, these should be separate.
Of course, you need to a catch a more specific exception than you currently are (don't catch the base class Exception!) and you should just throw instead of throw e if you need to rethrow the exception after logging, cleanup, etc.
You could emulate C#'s TryParse method signatures:
class Program
{
static void Main(string[] args)
{
Exception ex;
Console.WriteLine("trying 'ex'");
if (TryHelper("ex", out ex))
{
Console.WriteLine("'ex' worked");
}
else
{
Console.WriteLine("'ex' failed: " + ex.Message);
Console.WriteLine("trying 'test'");
if (TryHelper("test", out ex))
{
Console.WriteLine("'test' worked");
}
else
{
Console.WriteLine("'test' failed: " + ex.Message);
throw ex;
}
}
}
private static bool TryHelper(string s, out Exception result)
{
try
{
HelperMethod(s);
result = null;
return true;
}
catch (Exception ex)
{
// log here to preserve stack trace
result = ex;
return false;
}
}
private static void HelperMethod(string s)
{
if (s.Equals("ex"))
{
throw new Exception("s can be anything except 'ex'");
}
}
}
Another way is to flatten the try/catch blocks, useful if you're using some exception-happy API:
public void Foo()
{
try
{
HelperMethod("value 1");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
try
{
HelperMethod("value 2");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
// ... more here if needed
}
An option for retry (that most people will probably flame) would be to use a goto. C# doesn't have filtered exceptions but this could be used in a similar manner.
const int MAX_RETRY = 3;
public static void DoWork()
{
//Do Something
}
public static void DoWorkWithRetry()
{
var #try = 0;
retry:
try
{
DoWork();
}
catch (Exception)
{
#try++;
if (#try < MAX_RETRY)
goto retry;
throw;
}
}
In this case you know this "exception" probably will happen so I would prefer a simple approach an leave exceptions for the unknown events.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
if(!HelperMethod(s1))
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
if(!HelperMethod(s2))
{
return ErrorOfSomeKind;
}
}
return Ok;
}
catch(ApplicationException ex)
{
throw;
}
I know that I've done the above nested try catch recently to handle decoding data where two third party libraries throw exceptions on failure to decode (Try json decode, then try base64 decode), but my preference is to have functions return a value which can be checked.
I generally only use the throwing of exceptions to exit early and notify something up the chain about the error if it's fatal to the process.
If a function is unable to provide a meaningful response, that is not typically a fatal problem (Unlike bad input data).
It seems like the main risk in nested try catch is that you also end up catching all the other (maybe important) exceptions that might occur.
There has already been a question posted here which is very similar. Mine is extending that question a bit more. Say you want to catch multiple types of exception but want to handle it the same way, is there a way to do something like switch case ?
switch (case)
{
case 1:
case 2:
DoSomething();
break;
case 3:
DoSomethingElse()
break;
}
Is it possible to handle few exceptions the same way . Something like
try
{
}
catch (CustomException ce)
catch (AnotherCustomException ce)
{
//basically do the same thing for these 2 kinds of exception
LogException();
}
catch (SomeOtherException ex)
{
//Do Something else
}
Currently there is no language construct to accomplish what you want. Unless the exception all derive from a base exception you need to consider refactoring the common logic to a method and call it from the different exception handlers.
Alternatively you could do as explained in this question:
Catch multiple Exceptions at once?
Personally I tend to prefer the method-based approach.
You should really have a BaseCustomException and catch that.
This is copied from another posting, but I am pulling the code to this thread:
Catch System.Exception and switch on the types
catch (Exception ex)
{
if (ex is FormatException || ex is OverflowException)
{
WebId = Guid.Empty;
return;
}
throw;
}
I prefer this to repeating a method call in several catch blocks.
In vb.net, one can use exception filters to say, e.g.
Catch Ex As Exception When TypeOf Ex is ThisException Or TypeOf Ex is ThatException
Unfortunately, for whatever reasons, the implementors of C# have as yet refused to allow exception filtering code to be written within C#.
You shouldn't be catching this many custom exceptions,however if you want you can create a common BaseException and catch that.
I've never actually done this or anything like it, and I don't have access to a compiler for testing purposes but surely something like this would work. Not sure how to actually do the type comparison or if C# would let you replace the if statements with a case statement.
try
{
}
catch (System.Object obj)
{
Type type;
type = obj.GetType() ;
if (type == CustomException || type == AnotherCustomException)
{
//basically do the same thing for these 2 kinds of exception
LogException();
}
else if (type == SomeOtherException ex)
{
//Do Something else
}
else
{
// Wasn't an exception to handle here
throw obj;
}
}