I have a method calling combo as below:
Void MainMethod()
{
try
{
for(i = 0; i < 10; i++)
{
Childmethod_1();
}
}
catch(Exception ex)
{
throw ex;
}
}
Childmethod_1()
{
try
{
Childmethod_2();
}
catch(Exception ex)
{
Report(ex);
}
}
Childmethod_2()
{
try
{
[Block of Code]
}
catch(Exception ex)
{
throw ex;
}
}
Report(ex) in the Childmethod_1() is used to log the exception details into Database. If there is an exception occures in the Childmethod_2() whenever 'i' in the MainMethod(): For Loop is 4, will this exception block the rest 6 from the action?
The throw from Childmethod_2 will be caught by the catch from Childmethod_1 and logged to DB too. That catch block does not throw it again, so the exception will not be seen in your main loop, which will not be interrupted.
By the way,
catch(ex)
{
throw ex;
}
isn't only bad practice, it's completely useless. Why not just let the exception happen? Furthermore, the exception sent will not be complete, you'll lose the stack trace. If you really wish to do so, just throw like that:
catch(ex)
{
throw;
}
The answer to your question depends on implementation of Report(ex) method. If it doesn't rethrow the exception, but only stored exception data into the DB, then all iterations of your loop will be executed regardless exceptions occurred. In this case you can simplify your code (look below). Note that in this case you should make sure that Report(ex) method can't throw other exceptions (for example accessing to the database).
void MainMethod()
{
for(i = 0; i < 10; i++)
{
Childmethod_1();
}
}
Childmethod_1()
{
try
{
[Block of Code]
}
catch(Exception ex)
{
Report(ex);
}
}
On the other hand if Report(ex) rethrows exception after storing data into the DB, then the exception will be caught in the catch block of MainMethod and other iterations will not be executed. In this case you can't omit the try-catch block in MainMethod. However ChildMethod_2 is still redundant.
Related
While looking on C# try catch tutorial, I got following question. My sample code as follows,
Inside mainMethod() , I need to call three separate methods. Inside testMethodOne(), I need to handle exception as. If testMethodOne() throws exception, without executing testMethodTwo(dt), mainMethod() throwing exception. I need to call testMethodTwo(dt); and testMethodThreee(dt); if testMethodOne() throws exception, how can I do it.
public void MainMethod(data dt){
try{
testMethodOne(dt);
testMethodTwo(dt);
testMethodThreee(dt);
}catch(Exception ex){
throw ex;
}
}
public void testMethodOne(dt){
try
{
// Block of code to try
}
catch (Exception e)
{
// Block of code to handle errors
}
}
I understood your question as follows (but I might be wrong, your questions is not very clear):
Even if one of your testMethods throws an exception, you still want to continue in the normal program flow with the other methods. If at least one of the method failed, mainMethod could then report this as AggregateException.
public void MainMethod(data dt)
{
var exceptions = new List<Exception>();
try
{
testMethodOne(dt);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
try
{
testMethodTwo(dt);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
try
{
testMethodThreee(dt);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
if (exceptions.Count > 0)
{
throw new AggregateException(exceptions);
}
}
It seems as if you want exceptions to alter the flow of your main method without breaking everything. One easy method is to make each 'testmethod' return a boolean.
public bool testMethodOne(dt){
try
{
// Block of code to try
return true;
}
catch (Exception e)
{
// Block of code to handle errors
return false;
}
}
Then in your main code you can go
if(!testMethodOne(dt))
if(!testMethodTwo(dt))
if(!testMethodThree(dt))
//log that all methods failed
The above snippet would try each method until it finds one that succeeds. If that's not the behaviour you are looking for can you reword your question to make it clearer? If you want the opposite to happen just get rid of the ! and it will go until one fails. Alternatively you could put a throw in your catch statement in each of the testMethods, and that would stop execution once one is reached as well.
My simple example is:
void FixedUnalterableMethod()
{
try
{
throw new Exception("Exception 1"); //line 12.
}
finally
{
throw new Exception("Exception 2"); //line 16.
}
}
void Method1()
{
try
{
FixedUnalterableMethod(); //line 24.
}
catch (Exception ex)
{
var messageWithStackTrace = ex.ToString(); //line 28.
Console.WriteLine(messageWithStackTrace);
}
}
The console output is:
System.Exception: Exception 2
at Program.FixedUnalterableMethod() in ...\Program.cs:line 16
at Program.Main(String[] args) in ...\Program.cs:line 24
The question is, how to be informed that the Exception 1 has occured?
Is there a way how to include Exception 1 in my StackTrace (in line 28.) ?
Of coure I can't modify the FixedUnalterableMethod() method!
Yes, this is possible, though pretty nasty!
It is a little known fact that CLR exceptions do not cause the execution of finally blocks until the exception has actually been caught. This is disguised somewhat because if an exception is not caught (and makes it out of Main) then the default behaviour of the CLR hosting code is to run finally blocks for you, giving the illusion that they always run.
However, there is a way to examine an exception before catching it, to decide if you want to catch it. Try this:
static bool StoreFirstException(Exception x, Action<Exception> store)
{
if (x.Message == "Exception 1")
{
store(x);
}
return true;
}
static void Method1()
{
Exception firstException = null;
try
{
FixedUnalterableMethod(); //line 24.
}
catch (Exception ex) when (StoreFirstException(ex, x => firstException = x))
{
Console.WriteLine(firstException);
Console.WriteLine(ex);
}
}
The catch... when feature lets you write a boolean expression to examine the exception. Here I check the message (the only distinguishing fact you've given me) and if it's the first exception I pass it to the store action.
The caller uses this callback to stash the first exception.
Then it votes to catch, which only then causes the finally block to execute, which throws the second exception. The same when clause examines it but this time doesn't offer it to store. So then I have both exceptions in the catch block and I log them both. My console shows the two exceptions with the correct source line numbers.
Here's version that doesn't look at the message; it just assumes the first exception it see must be the interesting one. Also it's neater to use a nested function:
static void Method1()
{
Exception firstException = null;
bool StoreFirstException(Exception x)
{
if (firstException == null) firstException = x;
return true;
}
try
{
FixedUnalterableMethod(); //line 24.
}
catch (Exception ex) when (StoreFirstException(ex))
{
Console.WriteLine(firstException);
Console.WriteLine(ex);
}
}
If the "exception type" is literally the same you probably have little choice but the examine the Message property, which can be problematic to say the least.
Looking at that code again you will only ever see the 1 exception anyway, the one on line 16.
Thanks to #Daniel Earwicker the working solution is:
void FixedUnalterableMethod()
{
try
{
throw new Exception("Exception 1"); //line 12.
}
finally
{
throw new Exception("Exception 2"); //line 16.
}
}
void Method1()
{
bool CatchException(Exception ex)
{
//Log...
Console.WriteLine(ex.ToString());
return true;
}
try
{
FixedUnalterableMethod(); //line 24.
}
catch (Exception ex) when (CatchException(ex))
{
//do something with the lastest exception
}
}
The title is a bit misleading but the issue seems very straight-forward to me. I have try-catch-finally block. I want to execute the code in the finally block only if an exception was thrown from the try block. The structure of the code right now is:
try
{
//Do some stuff
}
catch (Exception ex)
{
//Handle the exception
}
finally
{
//execute the code only if exception was thrown.
}
Right now the only solution I can think of is setting a flag like:
try
{
bool IsExceptionThrown = false;
//Do some stuff
}
catch (Exception ex)
{
IsExceptionThrown = true;
//Handle the exception
}
finally
{
if (IsExceptionThrown == true)
{
//execute the code only if exception was thrown.
}
}
Not that I see something bad in this but wonder if there is another(better) approach to check if there's a thrown exception?
What about something like:
try
{
// Do some stuff
}
catch (Exception ex)
{
// Handle the exception
// Execute the code only if exception was thrown.
}
finally
{
// This code will always be executed
}
That's what Catch block are made for!
Don't use finally for this. It is intended for code that should always execute.
What exactly is the difference, in terms of when to execute, between
//Handle the exception
and
//execute the code only if exception was thrown.
I can't see any.
You don't need finally after all:
try
{
//Do some stuff
}
catch (Exception ex)
{
//Handle the exception
//execute the code only if exception was thrown.
}
The Finally part of a Try / Catch statement is always fired regardless of whether any exceptions have been found. I would recommend you don't use it in this scenario.
try
{
// Perform Task
}
catch (Exception x)
{
//Handle the exception error.
}
Finally
{
// Will Always Execute.
}
i am trying to handle exception and save that exception in database
Function1()
{
try
{
for(int i=0;i<dt.rows.count;i++)
{
Function2();
}
}
catch(exception ex)
{
saveInDB(ex.message.tostring(),id);
}
}
Function2()
{
try
{
function3()
}
catch(exception ex)
{
throw ex;
}
}
Function3()
{
try
{
function4()
}
catch(exception ex)
{
throw ex;
}
}
Function4()
{
try
{
code;
}
catch(exception ex)
{
throw ex;
}
}
suppose i got a exception in method4 then it will throw it to function3->Function2->function1 and then function1 will write exception in database.
but after writing exception in DB i want to continue for loop.
so how should i do?
but after writing exception in DB i want to continue for loop
That is only possible by putting an (extra) try/catch inside the for loop. You should do so only if the next round of the loop is independent and you are certain there is no harm done to your system.
Ask yourself: After an unknown error, do I still dare to write business-data to the database?
Notice that your code is in violation of some best-practices:
throw ex; resets the stack-trace. Replace it with throw;
when the catch blocks in function2 - function4 don't do anything with the exceptions, remove the try/catch altogether.
You can put your try-catch into the for loop's body:
Function1()
{
for(int i=0;i<dt.rows.count;i++)
{
try
{
Function2();
}
catch(Exception ex)
{
saveInDB(ex.message.tostring(),id);
}
}
}
Keep in mind, however, that IO such as saving to DB may be pretty unreliable (and slow). This in turn might lead to further exception being thrown in your catch, which will tear down your loop.
Therefore it might be better to store all thrown exception in a data structure and dump them to the DB at once. This way the loop runs for each and every row.
Function1()
{
var errors = new LinkedList<Exception>();
for(int i=0;i<dt.rows.count;i++)
{
try
{
Function2();
}
catch(Exception ex)
{
errors.AddLast(ex);
}
}
if(errors.Count > 0)
{
// now you got all exception in errors and can dump
// them in one block
}
}
As long as any try-catch block throws the exception, the program cannot continue.
If you want your program to be continue after exception handling, my suggestion would be not to use:
throw ex;
If you need to continue looping after an exception within the loop, you need to add a try/catch block within the loop as below;
try{
for(int i=0; i<10; i++){
try{
//do your work here
}
catch (Exception e){
//write to db here and then it will continue in the for loop
}
}
//rest of the code
}
catch (Exception ex){
//write to db
}
I'm trying to write some code that catches a particular exception and throw a more useful one for something higher up the call stack to deal with but also catch more general exceptions and handle them.
The code is something like this:
try
{
// Do stuff
}
catch (SomeException e)
{
throw new SomeExceptionWithContextInfo();
}
catch (Exception e)
{
// Handle unexpected exception gracefully
}
The problem I'm having is that the general exception is catching my new exception. is there a way to avoid this?
My current solution involves checking the type of the exception and throwing it again if it's type is what I just created.
The code you've posted should work, as shown in this test app:
using System;
class OtherException : Exception {}
class Test
{
static void Main(string[] args)
{
try
{
Foo();
}
catch (OtherException)
{
Console.WriteLine("Caught OtherException");
}
}
static void Foo()
{
try
{
string x = null;
int y = x.Length;
}
catch (NullReferenceException)
{
throw new OtherException();
}
catch (Exception)
{
Console.WriteLine("Caught plain Exception");
}
}
}
This just prints "Caught OtherException" not "Caught plain Exception". Are you sure you don't have a nested try block in your real code? Could you post a short but complete example which shows your problem?
Do you really need to catch Exception in your method though? That's very rarely a good idea.
You're doing it right. The general exception will not catch the specific one.
The code you posted is the way to do it (catch for more specific exception must appear first).
I suggest looking again at the code, as either they are not in that order, or the code isn't actually throwing that exception type.
Here is a link on msdn about try-catch: http://msdn.microsoft.com/en-us/library/0yd65esw(VS.80).aspx
Don't catch general exceptions might be the answer? Find out which Exceptions that can be thrown and catch them separately.
try { // Outer try/catch
DoSomething();
try {
/* */
} catch(NotGeneralException e) {
/* */
} catch(AnotherNotGeneralException e) {
throw new SomeOtherException("Exception message");
}
} catch(SomeOtherException e) {
/* */
}
Alternatively only catch a general exception and rethrow SomeOtherExcepion
try {
} catch(Exception e) {
throw new SomeOtherException("Exception message");
}