How to handle exception in catch block? - c#

I am trying to get the ideal way to handle exception. I googled & read that I should put try catch in the catch block as well to handle but what if any exception occurs in the nested block itself.
try
{
int a = 10;
int b = 0;
int c = a / b;
Console.WriteLine(c);
Console.ReadKey();
}
catch (Exception ex)
{
int a = 10; int b = 0;
int c = a / b;
Console.WriteLine(ex.Message.ToString());
Console.ReadKey();
}
finally
{
Console.WriteLine("Some Exception");
}
On googling I read that it should be decorated as below:
If exception occurs in Catch block itself then how to handle it in C#?
If exception occurs in Catch block itself then how to handle it in C#?
What happens if an exception occurs in Catch block in C#. Also what would be the caller result in that case
try
{
int a = 10;
int b = 0;
int c = a / b;
Console.WriteLine(c);
Console.ReadKey();
}
catch (Exception ex)
{
try
{
}
catch(Exception innerEx)
{
// What if exception here also occurs.
}
}
finally
{
Console.WriteLine("Some Exception");
}
If I do this way, then it will stuck in an infinite try-catch block.
I think there would be some better or the right way to handle this scenario.

I think there would be some better or the right way to handle this scenario.
No snark intended in this but simply, don't allow an exception to happen in the first place.
A try...catch is a language construct that ensures you handle an edge case or error you didn't mitigate and design for in the first place, hence why it's exceptional code.
In your code, you're simply throwing an error because of a division by 0, but in the real-world, you want to handle that and alert the user (or developer, or server, or whatever), and then handle the actual exceptional code, example:
static void PrintError()
{
Console.WriteLine("You must enter a valid number between {0} and {1}, excluding 0", int.MaxValue, int.MinValue);
}
static void Main(string[] args)
{
try {
int a = 10;
int b = 0;
PrintError(); // Tell user to enter valid numbers
while (b == 0) {
string user_input = Console.ReadLine();
if (int.TryParse(user_input, out b)) { // is it an actual number?
if (b == 0) { // no 0's remember user!??
PrintError();
} else {
// ok, everything checks out, so do what the system can actually handle without throwing an error
Console.WriteLine("a/b = {0}", (a / b));
}
} else {
PrintError();
}
}
} catch (Exception ex) {
Console.WriteLine("Something exceptional happened: {0}", ex);
}
}
This example could be simplified further, but it demonstrates there isn't an exception that could actually occur except something that is actually exceptional (i.e. out of memory error or some other system error).
In the event of larger code bases with multiple classes, the exception handler and finalizer would be where you could clean up resources acquired in other areas of the code, like closing a socket or file handle to ensure data is not lost.
In the event an error happens in the exception handler (something that can and does happen), you need to be aware of that and know what might happen in that case.
In the event of a C# application utilizing the .NET framework, an exception thrown within an exception will just cause the application to crash with the inner exception stack trace (versus the "outer" exception that's probably more relevant to the actual exception) if not handled.
There's plenty of "wrong" ways to handle exceptions (like not handling them at all), but there's not really a "right" way given the variable nature of exceptions.
Hope that can help.

First of all you need to know what does try,catch and finally works lets start:
Try: In this block we can write code which have the possibilities to throw some error (Better practice is to write code part in it.)
Catch: It is responsible to show error and what to do if error arises(Like in your code 10/0 throws error which can be handled in this section.)
Finally: Code written in this part will execute any how weather any error comes in or not.
Now for your query it would be better that you can use If...else in finally and code put in that part would be kept in try catch block.
For example:
bool flagCatch=false;
try
{
int a = 10;
int b = 0;
int c = a / b;
Console.WriteLine(c);
Console.ReadKey();
}
catch (Exception ex)
{
//Error handling
flagCatch=true;
Console.WriteLine(ex.Message.ToString());
Console.ReadKey();
}
finally
{
try
{
if(flagCatch)
{
//Code
}
else
{
//Code when error not comes
}
}
catch(Exception err)
{
//Error handling
}
}

I would go with the comment of Tieson T. . From my point of view it is an design issue.
I could also build an example with if statements -> if that goes wrong, I perform failure handling -> if the failure handling goes wrong, I perform failure handling, If the failure handling goes wrong ....
To make the code more readable, you can try to "hide" the try-catch blocks in method like:
static void PerformInTryCatch<T, TException>(Action<T> action, T obj) where TException : Exception
{
try
{
action(obj);
}
catch (TException exception)
{
// Perform some logging
}
}
Hope that helps.

Related

C# Compare Exceptions

I have a piece of code that sometimes throws an exception and sometimes doesn't. Depending on IO and network, different kinds of exception might be thrown. I have a wrapper for that code that shall retry the failing statement, say 10 times until it succeeds. If the exception does not go away after the 10th time, I rethrow it. Until now, I know what to do. Currently, I have something like this:
private void ExecuteStatement(Action statementToExecute)
{
while (true)
{
int exceptionCount = 0;
try
{
statementToExecute.Invoke();
// statement finished successfully
break;
}
catch (Exception e)
{
if (!IsFrameworkException(e))
throw; // rethrow as it isn't a framework exception
// we know now that it's a framework exception
exceptionCount++;
if (exceptionCount >= MaxRetriesOnFrameworkException)
throw;
}
}
}
The issue is the following: I want to reset the counter in case the exception changes (i. e. different type, different stacktrace, different message). I know how to compare them individually, but I want to know if there's a standard C# way of accomplishing this.
Edit: Here's the code of IsFrameworkException:
private bool IsFrameworkException(Exception e)
{
Exception rootCause = e.GetBaseException();
return rootCause.GetType() == typeof(WebException);
}
This is not specifically related to exception handling, but a simple way to keep counters by a specific key is to use a Tuple as the key (it implements equality by value out of the box).
Note that this doesn't reset the counter on key change, it justs keeps separate counters for each key:
readonly Dictionary<Tuple<Type, string, string>, int> _counters =
new Dictionary<Tuple<Type, string, string>, int>();
bool IsCountExceeded(Exception ex)
{
// create your key with whatever properties you consider to
// be "unique"
var key = Tuple.Create(ex.GetType(), ex.StackTrace, ex.Message);
// increase counter
int counter;
if (!_counters.TryGetValue(key, out counter))
{
counter = 1;
}
else
{
counter++;
}
_counters[key] = counter;
return counter > Max;
}
You can of course always make it more readable by creating your own class, which will implement Equals/GetHashCode properly.
I am also not sure that the stack trace can be considered as a unique property, and of course, catching and ignoring exceptions is usually a bad idea.
You should specify the exception type you want to catch. Place the catch blocks in order of most specific type to most generic type.
It is not clear if the exceptions all derive from FrameworkException or if you want to use Exception, the following assumes the former.
int exceptionCount = 0;
Type lastCaughtException = null;
while(true) {
try
{
statementToExecute.Invoke();
// statement finished successfully
break;
}
catch (WebException ex)
{
if(lastCaughtException == null || lastCaughtException != ex.GetType())
exceptionCount = 0;
else
exceptionCount++;
lastCaughtException = ex.GetType();
if (exceptionCount >= MaxRetriesOnFrameworkException)
throw;
}
catch (Exception) // if you do not want to log this you can completely omit this catch
{
throw; // rethrow as it isn't a framework exception
}
}
See also try-catch (C# Reference)

Is multiple try-catch in error sensitive code considered a good practice?

I have a code segment that is responsible for orchestrating the execution of a few modules and it is very sensitive to errors - I want to make sure I log and alert about every exception that occurs.
Right now I have something like this:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module A failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
try
{
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module B failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
// etc for other modules.
It looks to me that the multiple try-catch is making this segment less readable. Is it indeed the right thing to do?
Yes, it's the right thing.
But you should have the performance in in mind, maybe it's better to put all method calls in one try/catch and add stack trace and error information in the exception in the methiod itself.
public void ModuleA.DoSomethingA()
{
throw new Exception("Error in module A");
}
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
// get information about exception in the error message
}
You did well.
This way, you can process the error after each module. If you want to run it all and then do error handling, consider this alternative:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch(ModuleAException ex)
{
// handle specific error
}
catch(ModuleBException ex)
{
// handle other specific error
}
catch (Exception ex)
{
// handle all other errors, do logging, etc.
}
i think that depends on the approach that you want to follow.
It seems like you error messsages are different for each module that raises exception so i guess the approach that you followed is right.
you could have put the whole thing in a big try - catch block then in that case you will not know which module caused the exception as a generic excpetion gets printed.
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Either Module A or B failed", ex.Message);
// Log exception, send alerts, etc.
}
So if you want your exception handling to not be cleaner use the above code.
Otherwise what you followed is absolutely fine.

Can I execute multiple catch blocks that correspond to one try block?

Consider I have a try block that contains 3 statements, and all of them cause Exceptions. I want all the 3 exceptions to be handled by their relevant catch blocks.. is it possible ?
something like this-->
class multicatch
{
public static void main(String[] args)
{
int[] c={1};
String s="this is a false integer";
try
{
int x=5/args.length;
c[10]=12;
int y=Integer.parseInt(s);
}
catch(ArithmeticException ae)
{
System.out.println("Cannot divide a number by zero.");
}
catch(ArrayIndexOutOfBoundsException abe)
{
System.out.println("This array index is not accessible.");
}
catch(NumberFormatException nfe)
{
System.out.println("Cannot parse a non-integer string.");
}
}
}
Is it possible to obtain the following output? -->>
Cannot divide a number by zero.
This array index is not accessible.
Cannot parse a non-integer string.
Is it possible to obtain the following output?
No, because only one of the exceptions will be thrown. Execution leaves the try block as soon as the exception is thrown, and assuming there's a matching catch block, it continues there. It doesn't go back into the try block, so you can't end up with a second exception.
See the Java tutorial for a general lesson in exception handling, and section 11.3 of the JLS for more details.
If you want to catch multiple exceptions, you have to split your code across multiple try/catch blocks.
A better approach is to validate your data and log errors without triggering Exceptions to do this.
To add to Jon's answer, while you won't catch multiple exceptions from a single try block, you can have multiple handlers handle a single exception.
try
{
try
{
throw new Exception("This is an exception.");
}
catch(Exception foo)
{
System.Console.WriteLine(foo.Message);
throw; // rethrows foo for the next handler.
}
}
catch(Exception bar)
{
System.Console.WriteLine("And again: " + bar.Message);
}
This produces the output:
This is an exception.
And again: This is an exception.
this is a REALY BAD PRACTICE, but you can do next (solve your problem using finally block):
private static void Main()
{
int[] c={1};
String s="this is a false integer";
try
{
int z = 0;
int x = 5/z;
}
catch (ArithmeticException exception)
{
Console.WriteLine(exception.GetType().ToString());
}
finally
{
try
{
c[10] = 12;
}
catch(IndexOutOfRangeException exception)
{
Console.WriteLine(exception.GetType().ToString());
}
finally
{
try
{
int y = int.Parse(s);
}
catch (FormatException exception)
{
Console.WriteLine(exception.GetType().ToString());
}
}
Console.ReadKey();
}
}
Showing all of the exceptions handling at once is impossible. The goal of each exception catch is to have a different handling for each Exception type and otherwise it's pointless to print them all together.
No ,
It will not execute all three catch statements. The TRY block checks for error and then the execution comes out of the TRY block. Then Suitable catch will be executed. In your case, The ArithmeticException is in the Top of the Exception Hierarchy. So it will Execute and then the program terminates.
If you give, Catch(Exception e) before ArithmeticException then Exception catch will be executed... Better read about the SystemException Hierarchies at MSDN

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)
{
}
}

Order of execution of try catch and finally block

I am confused about the order of try, catch and finally block execution.
I also want to know when should I use try-catch block and what should I put in the try-catch block?
I also want to know if some exception comes in try block then if an action is taken corresponding to try block then which one is executed first catch or finally (which is always to be executed)?
After the execution of these two does control return to try block or it leave it?
If you have (note: this is not valid C#, see below for a valid example):
try {
// ... some code: A
} catch(...) {
// ... exception code: B
} finally {
// finally code: C
}
Code A is going to be executed. If all goes well (i.e. no exceptions get thrown while A is executing), it is going to go to finally, so code C is going to be executed. If an exception is thrown while A is executed, then it will go to B and then finally to C.
As an example, here's a valid C# code block from http://msdn.microsoft.com/en-us/library/dszsf989.aspx:
public class EHClass
{
void ReadFile(int index)
{
// To run this code, substitute a valid path from your local machine
string path = #"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
// Do something with buffer...
}
}
The reason to use try/catch/finally is to prevent your program to fail if there is an error in some code (A in the above example). If there is a problem, you can use catch part to catch the problem and do something useful, such as inform the user, log the exception to a log file, try again or try something different that you suppose might work instead of what you tried originally.
finally is used to ensure that some cleanup is performed. E.g. in A you might try to open a file and read it. If opening succeeds, but read fails, you will have an open file dangling. What you would like in that case is to have it closed, which you would do in finally block - this block always gets executed, guaranteeing the closing of the file.
Take a look here for more info:
http://msdn.microsoft.com/en-us/library/0yd65esw.aspx
http://www.c-sharpcorner.com/UploadFile/puranindia/75/Default.aspx
A try ... catch block is used to catch exceptions. In the try block you put the code that you expect may raise an exception.
If no exception occurs then the code in the try block completes as expected. If there's a finally block then that will execute next.
If an exception does occur then execution jumps to the start of the first matching catch block. Once that code is complete the finally block (if it exists) is executed. Execution does not return to the try block.
You should almost never use try/catch.
You should only catch exceptions that you can actually correct, and only when you're expecting them. Otherwise, let the caller handle the exception - or not.
If used, any catch clauses are executed first - only one of them.
Then, finally is "finally" executed.
This has been stated better in many places, but I'll try. The following code:
try
{
// Do something here
}
catch (Exception ex)
{
MessageBox.Show("Friendly error message");
}
does not fix the exception. It hides the exception so that the problem will never be fixed. That code has no idea which exception was thrown, because it will catch all of them, and it does nothing to correct the problem - it just tells the user a polite fiction.
The fact of the matter is that the code above should be replaced with the following:
// Do something here
This way, if the caller of this method knows how to fix particular problems, then the caller can fix them. You will not have removed that option from the caller.
If the caller does not know how to fix the problem, then the caller should also not catch the exception.
Here is an example (from MSDN) of using exceptions in a reasonable manner. It's a modified form of the example in the documentation of the SmtpFailedRecipientsException Class.
public static void RetryIfBusy(string server)
{
MailAddress from = new MailAddress("ben#contoso.com");
MailAddress to = new MailAddress("jane#contoso.com");
using (
MailMessage message = new MailMessage(from, to)
{
Subject = "Using the SmtpClient class.",
Body =
#"Using this feature, you can send an e-mail message from an application very easily."
})
{
message.CC.Add(new MailAddress("Notifications#contoso.com"));
using (SmtpClient client = new SmtpClient(server) {Credentials = CredentialCache.DefaultNetworkCredentials})
{
Console.WriteLine("Sending an e-mail message to {0} using the SMTP host {1}.", to.Address, client.Host);
try
{
client.Send(message);
}
catch (SmtpFailedRecipientsException ex)
{
foreach (var t in ex.InnerExceptions)
{
var status = t.StatusCode;
if (status == SmtpStatusCode.MailboxBusy || status == SmtpStatusCode.MailboxUnavailable)
{
Console.WriteLine("Delivery failed - retrying in 5 seconds.");
System.Threading.Thread.Sleep(5000); // Use better retry logic than this!
client.Send(message);
}
else
{
Console.WriteLine("Failed to deliver message to {0}", t.FailedRecipient);
// Do something better to log the exception
}
}
}
catch (SmtpException ex)
{
// Here, if you know what to do about particular SMTP status codes,
// you can look in ex.StatusCode to decide how to handle this exception
// Otherwise, in here, you at least know there was an email problem
}
// Note that no other, less specific exceptions are caught here, since we don't know
// what do do about them
}
}
}
Note that this code uses try/catch to surround a small piece of code. Within that try/catch block, if an SmtpException or SmtpFailedRecipientsException is thrown, we know what to do about it. If, for instance, we were to catch IOException, we would not know what it meant, or what to do about it. Any exception you don't actually know how to correct should not be caught, except maybe to add information to the exception, log it, and rethrow.
Here is an example:
try
{
someFunctionThatWorks();
functionThatThrowsAnException(); // As soon as this function throws an exception we are taken to the catch block
anotherFunction(); // <-- This line will never get executed
}
catch(Exception e)
{
// Here you can handle the exception, if you don't know how to handle it you should not be catching it
// After this you will not be taken back to the try block, you will go right to the finally block
}
finally
{
// Code here is always executed at the very end, regardless of whether an exception was thrown or not
}
I'd like to elaborate a bit on this and extend #icyrock.com answer with scenario when you rethrow the exception in the catch block so it is handled lower on the execution stack...
I gave it a try with the following code:
static void Main(string[] args)
{
try
{
// pick one:
// NormalExcecution();
// TroubleExcecution();
}
catch
{
Console.WriteLine("block D");
}
Console.ReadKey();
}
private static void NormalExcecution()
{
try
{
Console.WriteLine("block A");
}
catch (Exception)
{
Console.WriteLine("block B");
throw;
}
finally
{
Console.WriteLine("block C");
}
}
private static void TroubleExcecution()
{
try
{
Console.WriteLine("block A");
throw new Exception();
}
catch (Exception)
{
Console.WriteLine("block B");
throw;
}
finally
{
Console.WriteLine("block C");
}
}
So when there is no exception in block A, then the sequence is as follows (exception handling blocks are never hit):
Block A
Block C
When there's some problem with block A, the sequence is as follows:
block A
block B
block C
block D
Another words, the occurring exception is first handled by block B, then the finally clause is executed, only after that the exception is rethrown and handled lower on the execution stack (block D).
Please mind I may be wrong with what is actually going on under the hood of the .NET framework - I just present the results I observed :)

Categories

Resources