locked
accessing inner exceptions in embedded try catch RRS feed

  • Question


  • when we have a global try catch and a lot of small try catches inside the code. How do I get the embeded inner error that causes an error if this exception is located many levels inside the code?

    The thing is if I use throw exception , my code will not continue, right?, but the whole point of using try catch is that I want my code to continue execution.

    Thanks

     

    Wednesday, February 28, 2007 4:24 AM

Answers

  • Hi, rtaiss

    Yes, when error occured in part1 it goes to the last catch block, and if errors occured in part2 it goes to the first catch block then do the rest part3.

    If you want after doing code part2 and not let it do the part3 you can throw another exception in the first catch block.

    For example:

                Exception ex1 = new Exception("ex1");
                Exception ex2 = new Exception("ex22");
                Exception ex3 = new Exception("ex333");
                try
                {
                    //code part1
                    try
                    {
                        //code part2
                        throw ex1;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        throw ex2;// not let do part3
                    }
                    //code part3
                    throw ex3;
                }

               catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    It displays "ex1" "ex22" without "ex333"

    If you have further questions pls feel free to let me know.

    Thank you

    Thursday, March 1, 2007 2:18 AM
  • My advice is not to catch exceptions unnecessarily, but allow them to propagate upwards to the highest point in the call stack where you still have programmatic control.

    For example, in a Windows Form application, I would only catch exceptions in UI event handlers (e.g,. on button click event handlers), and display an appropriate message to the user. Any exceptions that happen lower down will only be caught at the top. It only makes sense to catch an exception lower down if you can recover successfully from it (consume the exception), or you need to add more info to it (in which case you re-throw the exception). This removes most try blocks (but you might still need them for finally statements).

    Why do you think you need to have all these embedded catch handlers?

    Thursday, March 1, 2007 1:54 PM
  • If you use throw on its own then the call stack for the exception is preserved, e.g.,

    try
    {
     try
     {
      throw new Exception()
     }
     catch (Exception ex)
     {
      throw;
     }
    }
    catch (Exception ex)
    {
     // ex will have call stack for embedded exception
    }

    This example has an embedded exception but we've already agreed that there are not usually necessary and should be avoided (this is also Microsoft's recommendation - see "Framework Design Guidelines" book).

    In your top level catch handler you could write the exception details to the Windows Event log (using System.Diagnostics.EventLog) or a log file (e.g., using log4net). To really solve a problem like this you may need to attach the debugger to the faulting process - see Remote Debugging in MSDN.

     

    Thursday, March 1, 2007 4:11 PM

All replies

  • Hi, rtaiss

    If an error occurred inside try block, it will break out (leave the left code in the block unexecuted) the block and to execute the corresponding catch block code.

    If you could be more specific, it may be clearer.

    Thank you

     

    Wednesday, February 28, 2007 4:41 AM
  •  

    yep, i m worried about production environnement like this:

    void mysub()

    {

    try

    {

          ....

          code part 1

    .     .....

        try{

                   code part 2

            }

           catch

           {

           }

    ....rest of my code part3

    catch

    {

     

    }

    }

    Now if an error occurs in the part of code number 2: code part 2 generates an error, the code continues execution and no errors is displayed, if the user tells me that the results are wrong, although there was an exception in code part2, try catch handles it and i don t have any idea that it s the code part 2 that causes an error.

    That s my problem.

    Thanks a lot.

    Thursday, March 1, 2007 12:50 AM
  • Hi, rtaiss

    Yes, when error occured in part1 it goes to the last catch block, and if errors occured in part2 it goes to the first catch block then do the rest part3.

    If you want after doing code part2 and not let it do the part3 you can throw another exception in the first catch block.

    For example:

                Exception ex1 = new Exception("ex1");
                Exception ex2 = new Exception("ex22");
                Exception ex3 = new Exception("ex333");
                try
                {
                    //code part1
                    try
                    {
                        //code part2
                        throw ex1;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        throw ex2;// not let do part3
                    }
                    //code part3
                    throw ex3;
                }

               catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    It displays "ex1" "ex22" without "ex333"

    If you have further questions pls feel free to let me know.

    Thank you

    Thursday, March 1, 2007 2:18 AM
  • You are correct that if you throw another exception, that it has to be caught at a higher level or you will eventually crash out.  You have to handle each one of these cases seperately.  Some time there is no way out but to exit the app, but in many cases you can survive it.

    Each time you catch an exception, you have to make a choice at that point:

    1. You can handle it... fix the problem in the catch however you have to... this can be done by some code that works around the problem, or a message to the user indicating what happened, and that they should not do that again. Tthe "full volume" example in your other thread on this subject is a good example of why you would want to alert the user of some external problem.

    2. You can't handle it where you are, but at a higher level it can be handled.  An example of this might be a 3D model loader, where you will load various pieces of the model... textures, geometry, animation data.  Maybe during the animation data load something was wrong enough to cause an exception that you caught, but you deside by design that this should be handled by a higher power... the model loader.  So you throw the exception again... you can copy any portion of the message (including the stack trace) and use it again in the re-throwing... that way you still have where it originally came from.

    Let me add at this point that maybe you have (say 6) different exceptions that you find can happen at the lower levels of the model loader.  This does not mean that any of these exact exceptions need to bubble up any further than the loader...

    Now when the model loader gets the exception, the only code that should have been skipped is other portions of loading that model, which was bad anyway... nothing you can do about it.  So now in the model loader catch, you might further anaylize the problem, and find there's nothing you can do but fail ... so you repackage the message, and maybe the stack trace, and throw a "Model exception".  All of the more granular exceptions you had in the model loader are now contained in the model loader, which just "returns" one type of exception, so higher in the code you don't have to check for every exception under the sun.... all your reporting here is that a model loaded improperly... it could have been because a file was missing, an arithmetic error, or something else.  Since you have kept a copy of the orignal text as part of the message, you can find out higher up the chain.

    3. Now in the part of the application that was loading an entire scene (cameras, models, scripts... all the things required for the application),  one of the exceptions you are checking for when loading a scene is the "model loader" exception....

    At this point, you have maybe a "third tier" ... or a higher level of desision to make.   If this scene can not be loaded, does it mean the application is not useful until that problem is corrected, or should we keep the app going and just allow another scene to be loaded.

    So in the scene loader catch that found that a bad model had been attempted to be loaded, we might do any of the following, depending on what our requirements are:

    1. If the one model is not a big deal to us, attempt to load the rest of the scene.

    2. If that one model means that the scene is useless, but our application is a scene viewer, then alert the user the scene is bad, and don't throw another exeception.

    3. If that one model means the app is useless (like if it's the main player in a video game), then we're out of luck... package the message data that has bubbled up from the beginning of this nightmare, and throw an even higher level exception... on that will be caught within "Main".  Now in the catch in "Main" where the most general execeptions are caught, we can make a nice message to the user what the problem is, and we can even use the message and stack data that we have been bubbling up by repackaging it however we want... it might be to display a bunch of junk the user can't comprehend (that's a joke), or to package up to be sent back in a bug report.

    Sorry I could not make this any less verbose :)

    Jim Tomasko

     

    Thursday, March 1, 2007 2:51 AM
  • My advice is not to catch exceptions unnecessarily, but allow them to propagate upwards to the highest point in the call stack where you still have programmatic control.

    For example, in a Windows Form application, I would only catch exceptions in UI event handlers (e.g,. on button click event handlers), and display an appropriate message to the user. Any exceptions that happen lower down will only be caught at the top. It only makes sense to catch an exception lower down if you can recover successfully from it (consume the exception), or you need to add more info to it (in which case you re-throw the exception). This removes most try blocks (but you might still need them for finally statements).

    Why do you think you need to have all these embedded catch handlers?

    Thursday, March 1, 2007 1:54 PM
  • ShellShock, i think you answered my question,

    My problem in my try catch exemple, above and recoded by Figo, is that I want the code part 3 to execute, that is, i want MessageBox.show(Ex3)  to happen. Therefore I only see that ShellShock's suggestion fixes the prblem, unless someone else can tell me how I can put many embedded try catches and still restore the source of the error that happens inside an embedded try catch but still let the code to continue execution after the error happens inside the embedded code.

    P.S: my main concern is that the user tells me that he doesn t get the toolbar for example, meaning that an error occured inside. My problem is how to modify my code, so that whenever an error happens i can keep a log of it. I mean what s the best practice to do so and what s used in real business and good practices :)

    Thanks amigos :)

    Thursday, March 1, 2007 3:05 PM
  • If you use throw on its own then the call stack for the exception is preserved, e.g.,

    try
    {
     try
     {
      throw new Exception()
     }
     catch (Exception ex)
     {
      throw;
     }
    }
    catch (Exception ex)
    {
     // ex will have call stack for embedded exception
    }

    This example has an embedded exception but we've already agreed that there are not usually necessary and should be avoided (this is also Microsoft's recommendation - see "Framework Design Guidelines" book).

    In your top level catch handler you could write the exception details to the Windows Event log (using System.Diagnostics.EventLog) or a log file (e.g., using log4net). To really solve a problem like this you may need to attach the debugger to the faulting process - see Remote Debugging in MSDN.

     

    Thursday, March 1, 2007 4:11 PM
  • the main reaso why i have embedded try catch 's is that there re little peaces of code that even if an exception occurs, i want the code after that peace of code to continue execution rather than jumping to the outer-global try catch

    Thanks amigo :)

     

    Friday, March 2, 2007 1:41 AM
  • In that case perhaps you should use try...finally (with no catch). The code in the finally block will always execute (even if an exception occurs).
    Friday, March 2, 2007 9:07 AM