Reputation: 5326
It was an interview question, quite simple, but I am not confident about the answer.
What happens if an exception occurs in catch block ?
I am trying to give an example small prog of what the interviewer was trying to ask me, please correct my program if it is not compiling, I am really new to this. Bottom line is what happens if an exception occurs in Catch and what will be the value of caller int hat case.
For instance, I have the following:
double Calculate(int x)
{
try
{
x = x/2;
}
catch(Exception ex)
{
Console.Writeline("Message: "+ ex.Message);
}
finally
{
x = 10;
}
return x;
}
double myResult = Calculate(x); //x can be any number or 0 for example
Now there are two questions:
What happens if an exception happens in catch block ? Also, how to resolve it ? (This is simple example of what the interviewer was asking a similar question).
What will happen to myResult if an exception happens in Calculate(x) method ?What will be its value in all cases ? (Please explain every case with an example)
I would like to understand this with a detailed explanation too.
Thank you so much.
Upvotes: 32
Views: 49982
Reputation: 256
To Explain it code wise . Here is the sample code using System;
public class Program
{
public static double Calculate(int x)
{
try
{
x = 2 / x;
}
catch (ArithmeticException ae)
{
x = 2 / x; // This will throw the error and programs terminates without returning any value.
Console.WriteLine("Message: " + ae.Message);
}
catch (Exception ex)
{
Console.WriteLine("Message: " + ex.Message);
}
finally
{
x = 10;
}
return x;
}
static void Main(string[] args)
{
double myResult = Program.Calculate(0);
Console.WriteLine(myResult);
}
}
}
The code behaves the same even if it is in catch block , unless there is try catch inside a catch block like this
public class Program
{
public static double Calculate(int x)
{
try
{
x = 2 / x;
}
catch (ArithmeticException ae)
{
try
{
x = 2 / x;
}
catch(Exception ex1)
{
Console.WriteLine("Message: " + ex1.Message);
}
Console.WriteLine("Message: " + ae.Message);
}
catch (Exception ex)
{
Console.WriteLine("Message: " + ex.Message);
}
finally
{
x = 10;
}
return x;
}
static void Main(string[] args)
{
double myResult = Program.Calculate(0);
Console.WriteLine(myResult);
}
}
}
Upvotes: 0
Reputation: 52
I agree with TheEvilPenguin. Just put a try/catch one more time in the catch portion. I didn't run the code, but the finally portion will always run regardless if there is an exception or not, therefore x is equal to 10.
Here is the crazy code I wrote today. As you can see, I put a try/catch in the catch portion of the code:
if (days >= 180 || inStock == false)
{
if (mainGetSet.OrderID != MainGetSet.EMAILCANCELO)
{
if (debugging == true)
{
MessageBox.Show("Here is where support will get an email instead of it being canceled. Order ID: " + mainGetSet.OrderID);
}
string subject = "Please check order " + mainGetSet.OrderID + " to ascertain if possible cancel action is needed.";
string body = "Dear Support \r\n \r\nPlease check order " + mainGetSet.OrderID + " to confirm if a possible cancel action is needed " +
"and please process manually. Here is the SKU " + childGetSet.Sku + ". Thank you. " +
" \r\n \r\n Kind Regards, \r\n IT Department";
sendEmail.SendEmailToSupport(subject, body);
// Database call to the cancel order DB
CanceledDB.AddJSONInfo(childGetSet);
//readyResponse = CancelKiboOrder.MakeOrderCanceled(token, mainGetSet.OrderID);
}
MainGetSet.EMAILCANCELO = mainGetSet.OrderID;
}
else
{
if (debugging == true)
{
MessageBox.Show("Here is where support will get an email about the backorder date. Order ID: " + mainGetSet.OrderID);
}
//DateTime backorder180 = new DateTime().AddDays(days);
//string backOrder = backorder180.ToString("yyyy-MM-dd'T'HH:mm:ss");
string backOrder = DateTime.UtcNow.AddDays(days).ToString("s") + "Z";
string ItemsQty = string.Empty;
for (int iq = 0; iq < jsonGetSet.OrderItemID.Count; iq++)
{
//ItemsQty += "{ \r\n \"autoAssign\":false,\r\n \"locationID\":169309,\r\n \"shipmentStatus\":\"READY\",\r\n \"itemAssign\":[ \r\n { \r\n \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n }\r\n ]\r\n }\r\n";
ItemsQty += " {\r\n \"shipmentStatus\":\"BACKORDER\",\r\n \"backOrderReleaseDate\":\"" + backOrder + "\",\r\n \"itemAssign\":[\r\n {\r\n \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n }\r\n ]\r\n }\r\n ";
if (jsonGetSet.OrderItemID.Count > 0 && iq < jsonGetSet.OrderItemID.Count - 1)
{
ItemsQty += ",";
}
}
if (debugging == true)
{
MessageBox.Show(ItemsQty);
}
string subject = "Please check backorder number " + mainGetSet.OrderID + " to ascertain the reason.";
string body = "Dear Support \r\n \r\nPlease check backorder number " + mainGetSet.OrderID + " to confirm the backorder. " +
"Here is the SKU " + childGetSet.Sku + "."+
" \r\n \r\n Kind Regards, \r\n IT Department";
sendEmail.SendEmailToSupport(subject, body);
readyResponse = Backorder.MakeOrderBackorder(token, mainGetSet.OrderID, ItemsQty);
}
if (debugging == true)
{
DebugOutput(readyResponse, textBox);
}
var parsedReady = new JObject();
try
{
parsedReady = JObject.Parse(readyResponse);
}
catch (Exception JEx)
{
if (debugging == true)
{
MessageBox.Show("The program threw an Exception: " + JEx);
}
else
{
string messageSubject = "There was a problem with the JSON for the BackOrder in KIBO.";
string messageBody = "There was a problem with the JSON for the BackOrder in KIBO. Error: " +
"\r\n \r\n \r\n Here is the JSON returned: " + parsedReady;
string kiboSendEmail = string.Empty;
kiboSendEmail = sendEmail.SendEmailCS(messageSubject, messageBody, JEx);
if (mainGetSet.OrderID != MainGetSet.EMAILCANCELO)
{
if (debugging == true)
{
MessageBox.Show("Here is where support will get an email instead of it being canceled. Order ID: " + mainGetSet.OrderID);
}
string subject = "Please check order " + mainGetSet.OrderID + " to ascertain if possible cancel action is needed.";
string body = "Dear Support \r\n \r\nPlease check order " + mainGetSet.OrderID + " to confirm if a possible cancel action is needed " +
"and please process manually. Here is the SKU " + childGetSet.Sku + ". Thank you. " +
" \r\n \r\n Kind Regards, \r\n IT Department";
sendEmail.SendEmailToSupport(subject, body);
// Database call to the cancel order DB
CanceledDB.AddJSONInfo(childGetSet);
//readyResponse = CancelKiboOrder.MakeOrderCanceled(token, mainGetSet.OrderID);
}
MainGetSet.EMAILCANCELO = mainGetSet.OrderID;
{
if (debugging == true)
{
MessageBox.Show("Here is where support will get an email about the backorder date. Order ID: " + mainGetSet.OrderID);
}
//DateTime backorder180 = new DateTime().AddDays(days);
//string backOrder = backorder180.ToString("yyyy-MM-dd'T'HH:mm:ss");
string backOrder = DateTime.UtcNow.AddDays(days).ToString("s") + "Z";
string ItemsQty = string.Empty;
for (int iq = 0; iq < jsonGetSet.OrderItemID.Count; iq++)
{
//ItemsQty += "{ \r\n \"autoAssign\":false,\r\n \"locationID\":169309,\r\n \"shipmentStatus\":\"READY\",\r\n \"itemAssign\":[ \r\n { \r\n \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n }\r\n ]\r\n }\r\n";
ItemsQty += " {\r\n \"shipmentStatus\":\"BACKORDER\",\r\n \"backOrderReleaseDate\":\"" + backOrder + "\",\r\n \"itemAssign\":[\r\n {\r\n \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n }\r\n ]\r\n }\r\n ";
if (jsonGetSet.OrderItemID.Count > 0 && iq < jsonGetSet.OrderItemID.Count - 1)
{
ItemsQty += ",";
}
}
if (debugging == true)
{
MessageBox.Show(ItemsQty);
}
string subject = "Please check backorder number " + mainGetSet.OrderID + " to ascertain the reason.";
string body = "Dear Support \r\n \r\nPlease check backorder number " + mainGetSet.OrderID + " to confirm the backorder. " +
"Here is the SKU " + childGetSet.Sku + "." +
" \r\n \r\n Kind Regards, \r\n IT Department";
sendEmail.SendEmailToSupport(subject, body);
readyResponse = Backorder.MakeOrderBackorder(token, mainGetSet.OrderID, ItemsQty);
}
if (debugging == true)
{
DebugOutput(readyResponse, textBox);
}
parsedReady = new JObject();
try
{
parsedReady = JObject.Parse(readyResponse);
}
catch (Exception Jx)
{
if (debugging == true)
{
MessageBox.Show("The program threw an Exception: " + Jx);
}
else
{
messageSubject = "There was a problem with the JSON for the BackOrder in KIBO.";
messageBody = "There was a problem with the JSON for the BackOrder in KIBO. Error: " +
"\r\n \r\n \r\n Here is the JSON returned: " + parsedReady;
kiboSendEmail = string.Empty;
kiboSendEmail = sendEmail.SendEmailCS(messageSubject, messageBody, JEx);
}
}
Upvotes: 0
Reputation: 9947
In case if its a child function the exception will be sent to the catch block of calling function
In case if its a main function the exception would be thrown and either handled by a calling method or unhanded
Secondly we don't write anything in catch
blocks which can cause an exception.
They are usually used to throw or log exception.
Even if there is something you can use the Finally
block so that any occupied resources can be relased.
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
Upvotes: 1
Reputation: 5682
An exception thrown in a catch
block will behave the same as an exception thrown without it - it will go up the stack until it is caught in a higher level catch block, if one exists. Doing this is quite normal if you want to change or wrap the original exception; i.e.:
public void MyStartMethod
{
try
{
//do something
MyBadMethod();
}
catch(MySpecialException mse)
{
//this is the higher level catch block, specifically catching MySpecialException
}
}
public void MyBadMethod()
{
try
{
//do something silly that causes an exception
}
catch (Exception e)
{
//do some logging
throw new MySpecialException(e);
}
}
public class MySpecialException : Exception
{
public MySpecialException(Exception e) { ...etc... }
}
In your case, myResult
will have whatever value it had before, if it's even still in scope.
Upvotes: 31
Reputation: 39268
An exception in the catch will basically behave as if there was no catch block there to begin with. You see this pattern in multilayered code where you rethrow exceptions. This is a slight variation on your example, but the result is very similar.
try
{}
catch
{
throw;
}
In the case above and in your case the exception is considered unhandled since it's still propagating up the stack.
There will be no return value. The program simply fails if there is no other catch block to deal with it.
Upvotes: 4
Reputation: 449
The info below will help (from a previous answer of mine to a related question). If your catch block throws an exception and there are no other catch blocks to handle it besides the one that caused it, it will continue to get re thrown then 'Windows handles it'.
If a exception occurs the CLR traverses up the call stack looking for a matching catch expression. If the CLR doen't finds a matching one, or the Exception gets re thrown each time, the Exception bubbles out of the Main() method. In that case Windows handles the Exception.
Event Handling of Console Applications is the easiest to understand, because there is no special Handling by the CLR. The Exception is leaving the Applications Thread if not caught. The CLR opens a window asking for debug or exit the application. If the user chooses to debug, the debugger starts. If the user chooses to close, the Application exits and the Exception is serialized and written to the console.
Upvotes: 3
Reputation: 5163
There is no real return-value. The exception will "return".
This is acceptable Code for compiler:
public bool fooMethod()
{
throw new NotImplementedException();
}
In your case myResult
will not be changed.
Upvotes: 0