30

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:

  1. 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).

  2. 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.

Jasmine
  • 5,186
  • 16
  • 62
  • 114
  • Calculate() return void!!! can't be compiled – A.T. Oct 10 '13 at 05:03
  • @Arun: What did you do to my finally block :0 Why you removed it :0 Interviewer had finally block too. I forgot that and upon Rex's note, I added it – Jasmine Oct 10 '13 at 05:13
  • 1
    Any empty finally block does nothing, and has no bearing on the question. – Preston Guillot Oct 10 '13 at 05:14
  • @PrestonGuillot: Sorry, that was my mistake, I don't know what to put in finally. I wrote the same, I just gave an example and not sure how to completely describe my scenario with example. Please help. – Jasmine Oct 10 '13 at 05:17
  • Maybe you can put the finally block back in with some code as an example, as it _does_ get called if an exception is thrown in the catch block. – Alex Wiese Oct 10 '13 at 05:20
  • @alexw: I put the finally block, Arun removed it :( I will put it again. – Jasmine Oct 10 '13 at 05:23

7 Answers7

30

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.

slugster
  • 49,403
  • 14
  • 95
  • 145
TheEvilPenguin
  • 5,634
  • 1
  • 26
  • 47
  • Thank you TheEvilPenguin, so that means, in my case, assume there was no prior value of myResult, so it will have the default 0 of string if there is no finally block ? And otherwise, it will have value 10 as it has finally block ? – Jasmine Oct 10 '13 at 05:33
  • 2
    The `return x;` line of `Calculate` is never reached in your example if the `catch` block throws an exception. – Preston Guillot Oct 10 '13 at 05:45
  • 3
    @Divine In your current example it will have the value `10` as the `finally` block is **always** executed after the catch (except for when it's a StackOverflowException which cannot be caught). – slugster Oct 10 '13 at 05:45
  • @PrestonGuillot: That's a good point. Then what will happen :0 – Jasmine Oct 10 '13 at 05:47
  • @slugster: Ok assume I do not have finally. Then what would be the value of myResult ? But Preston says, the return value will nto be reahed at all. That makes sense too. So what will happen then how it will set 10 even if there is finally ? – Jasmine Oct 10 '13 at 05:48
  • 1
    Given your example, your program crashes. If you declare `myResult` outside of a `try/catch` block, where the `try` block includes the assignment to `myResult`, that assignment never happens, so `myResult` has whatever value it had before entering the `try` block. – Preston Guillot Oct 10 '13 at 05:49
  • 1
    @Divine You would have the answer to all this if you just tried it yourself. – slugster Oct 10 '13 at 07:05
  • @slugster: I am afraid that didn't work for me. Anyway will try again – Jasmine Oct 10 '13 at 07:12
  • @slugster It was an ok answer until the edit, *now* it's great. Thanks – TheEvilPenguin Oct 10 '13 at 20:35
4

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.

TGH
  • 38,769
  • 12
  • 102
  • 135
  • Thank you. Which means what will be the value of myResult ? 0 ? I didn't have any value for myResult. So will this be a default value of string i.e 0 ? – Jasmine Oct 10 '13 at 05:38
  • 1
    myResult will not be assigned a new value since the function fails before the value is returned. It would still have its original value, but if the exception is not handled the program will crash, and the original value of myResult will be lost when you are forced to restart the program. – TGH Oct 10 '13 at 23:53
3

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.

JuStDaN
  • 449
  • 2
  • 7
1

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.

MSDN DOCUMENTATION

  • Rex, that is what I told, but the interviewer idiot was forcing me to answer what happen if an exception occurs in catch. Do you mean that there can never be an exception in Catch anytime in the programming world ? – Jasmine Oct 10 '13 at 05:06
  • @Divine you are missing the finally block here – Vinay Pratap Singh Bhadauria Oct 10 '13 at 05:07
  • Thanks Rex, I will add finally block too, sorry, I am not that good in programming, learning daily :) – Jasmine Oct 10 '13 at 05:08
  • 3
    @rex you don't need a finally block (unless you are using it). Exceptions _can_ occur in catch blocks. The interviewer was asking what happens if one does get thrown, nothing about writing code to ensure an exception does not occur in a catch block. Also the finally block won't stop the exception from propagating up the stack. – Alex Wiese Oct 10 '13 at 05:13
  • @alexw: Thank you, yes interviewer was asking the same :( But he had finally block too in that question. Well what will happen if an exception occurs in catch and how to handle it ? :0 What will be the value of myResult: 0 or any other exception message ? I told interviewer that, it goes to finally. But he wasn't interested in that, he asked me what happens in catch even if finally is not there and an exception is thrown in catch :( I was clueless :( – Jasmine Oct 10 '13 at 05:15
  • @divine if an exception occurs in the catch it is exactly the same as it occurring outside of the try (eg. imagine you had no try/catch) except that if _do_ you have a finally block the code inside of that will be called first. – Alex Wiese Oct 10 '13 at 05:18
  • @alexw, divine i mentioned In case if its a child function the exception will be sent to the catch block of calling function. but still i need to make an edit to my answer – Vinay Pratap Singh Bhadauria Oct 10 '13 at 05:19
  • 1
    @alexw what if the exception is in the catch of main function only – Vinay Pratap Singh Bhadauria Oct 10 '13 at 05:20
  • 1
    @Rex the same as what would happen if there was no try/catch. The exception would be thrown and either handled by a calling method or unhandled – Alex Wiese Oct 10 '13 at 05:22
  • @alexw, Rex thank you so much, that helps me a lot. So assume myResult had no value at all, meaning some default value of string 0. So I assume te value will be 0 if an exception occurs in this case without a finally block. And if it is with a finally block like in my question, the value will be 10 ? – Jasmine Oct 10 '13 at 05:31
  • These statements: `Secondly we don't write anything in catch blocks which can cause an exception. They are usually used to throw or log exception.` are erroneous. Code in a catch block can absolutely throw an exception. Take the instance of wanting to log the exception. You might not be able to access the database or you might not have permissions to the log file anymore. – eidylon Jan 05 '18 at 20:33
0

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.

Micha
  • 5,117
  • 8
  • 34
  • 47
0

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);






                            }

                        }
Justin W
  • 52
  • 1
  • 6
0

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);
    }
}
}
J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
dead_webdev
  • 164
  • 2
  • 9