none
Try catch block

    Question

  • What is the proper way of dealing with exception?

    Would you put the try catch block in the most out side loop of the program and catch all errors there to avoid program to crash?

    Another side question:

    How can you make the program stop at the point of error instead of propagate to the most out side try catch block in debug mode?

    When you run the release mode, the program should not stop at the point of error and instead go execute try catch?

    Thanks in advance,

    Tuesday, February 21, 2012 3:19 PM

Answers

  • It is my personal view that using try .. catch exception handling on pretty much everything is bad practice and very lazy. Any possibility of error should be dealt with by your code logic. The only exceptions for me are file and network access. Everything else should be dealth with via code logic - in other words you should be able to predict every possible error that could occur in a given routine and deal with it. This is good programming.

    Take for example a devide by zero exception. Simply prevent it from heppening! For example:

    if (num2 > 0)
       int result = num1 / num2;
    else
       // either do nothing or remind the user not to devide by zero

    In the case of file access - anything can happen really. In this case you should use multiple catches starting with the most specific error to the most general (IOException). As far as I'm concerned the general Exception class should not be used except in conjunction with legacy COM libraries. Even then there are better ways of handling errors, it simply takes time.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.


    Tuesday, February 21, 2012 4:24 PM
  • What is the proper way of dealing with exception?

    Would you put the try catch block in the most out side loop of the program and catch all errors there to avoid program to crash?

    Another side question:

    How can you make the program stop at the point of error instead of propagate to the most out side try catch block in debug mode?

    When you run the release mode, the program should not stop at the point of error and instead go execute try catch?

    Thanks in advance,

    Proper way of dealing with exceptions: Handle it as early as possible.

    How can you make the program stop.....: This needs a small setting in your VS.

    Goto Debug -> Exceptions and you should see this window. Check the pencil marked checkbox.

    Even cool, go to your thread stack, right click on the last thread which is currently executing and select "Unwind to this frame". VS undoes your exception and you are in debugging mode again.

    In release mode, the program wont stop and go on executing.


    Planet Earth is at risk. Global warming is on a high tide.
    Take Responsibility. Plant Trees. Keep your City Clean and Green.

    Mark all Helping Posts and Close your Threads. Keep the Forum Green.
     - Arun Kumar Allu


    Tuesday, February 21, 2012 6:31 PM
  • mpt;

      Bet you didn't know you were igniting a flame here...   As it turns out there are two camps to excpetion handling, both are appropriate under the proper setting.  One camp teaches to always handle as low as possible, the other teaches to throw to higher levels. 

    Example:  Let's say you are doing an SQL Query in application code where the user wants a customer based on last name.  The SQL Server throws a SQL level exception that has no meaning to the user.  Do you handle it lower in the code or do you let the user see the SQL Error?  If you handle it lower in the code what message will the user see when that record can't be seen? 

    As Noam pointed out typically you want separate low leve exceptions that are anticipating specific errors in the given context of the program.  For example a FileOpen request is being attempted to a non existing file... There should either be an application check for file exists or an exception handler for FileNotThere...

    From there every application should wrap ALL Exceptions at the EXCEPTION layer otherwise known as the System.Exception layer.  This wrapper will catch all exceptions not thought of and allow the program to gracefully do something. 

    Finally don't over look the importance of proper error messaging, as it is the ONLY way to obtain run-time metrics on the validity of the code.  Some argue that each error thrown should have a unique ID...  By doing it this way you can run reports that answer the question "What's this appilcations' top problems?" 


    JP Cowboy Coders Unite!

    Tuesday, February 21, 2012 7:16 PM
  • If you expect a certain exception is most likely to occur, put it in the first catch. Put other types of exceptions, in descending order of likelihood of appearance, below that.

    I think you mean most specific type down to most general type. If the most general type is the most likely, hence you place it first, it will catch more specific errors so you lose specific handling.


    Regards David R
    ---------------------------------------------------------------
    Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
    Every program eventually becomes rococo, and then rubble. - Alan Perlis
    The only valid measurement of code quality: WTFs/minute.

    Tuesday, February 21, 2012 7:26 PM
  • Everyone has their opinions on this one. I'm probably somewhere in between everyone else.

    You should anticipate every possible exception. Write code to avoid it. If that's not possible, catch expected exceptions as close to the site of the exception as reasonably possible if you can provide some sort of graceful behavior. File I/O is a good example - if the file is in use, you may want to quickly catch that exception and just try again. If the file doesn't exist or they don't have permissions, you may want to display a message for the user. In those situations, catch it close to the exception and handle it gracefully.

    If you cannot provide a graceful solution, just don't catch it. At the outer-most level of your application, you may have a try/catch that writes exceptions to a log and just provides a generic "oops, something went wrong" message for users. That should only catch extreme and unpredictable errors, which can't possibly be handled. When those errors occur, a log should be written, admins should be getting emails, red lights should be going off.

    The two most broken rules for exception handling:

    1. Never swallow an error message. If an exception is happening, you either need to deal with it or flag it for someone to track down and deal with later (log message, email, etc)
    2. Never catch an exception if you can't do anything useful with it. If your entire plan is just to show an ugly error message to the user, you may as well let them see the real error.

    In other words, deal with exceptions you can deal with. If you can't deal with them, make sure someone who can is notified when they occur.


    Check out My Blog. Now updated to actually work!

    Wednesday, February 22, 2012 10:28 PM
  • You should put try-catch wherever you have a chance to have an error.

    The best practice is to handle each of the errors that you get with multiple catch-es.

    That way you'll know if you have an error that you did not think of.

    That's for developement.

    Of course, on production, you'll make a try on the outside loop in order for your code not to crash.

    BUT, you have to have someway of knowing that an error happened, so you can improve your app.

    For example, you can use an automated email, or a data-base that you can check for errors.

    Noam B.



    Do not Forget to Vote as Answer/Helpful, please. It encourages us to help you...

    Tuesday, February 21, 2012 3:34 PM

All replies

  • You should put try-catch wherever you have a chance to have an error.

    The best practice is to handle each of the errors that you get with multiple catch-es.

    That way you'll know if you have an error that you did not think of.

    That's for developement.

    Of course, on production, you'll make a try on the outside loop in order for your code not to crash.

    BUT, you have to have someway of knowing that an error happened, so you can improve your app.

    For example, you can use an automated email, or a data-base that you can check for errors.

    Noam B.



    Do not Forget to Vote as Answer/Helpful, please. It encourages us to help you...

    Tuesday, February 21, 2012 3:34 PM
  • It is my personal view that using try .. catch exception handling on pretty much everything is bad practice and very lazy. Any possibility of error should be dealt with by your code logic. The only exceptions for me are file and network access. Everything else should be dealth with via code logic - in other words you should be able to predict every possible error that could occur in a given routine and deal with it. This is good programming.

    Take for example a devide by zero exception. Simply prevent it from heppening! For example:

    if (num2 > 0)
       int result = num1 / num2;
    else
       // either do nothing or remind the user not to devide by zero

    In the case of file access - anything can happen really. In this case you should use multiple catches starting with the most specific error to the most general (IOException). As far as I'm concerned the general Exception class should not be used except in conjunction with legacy COM libraries. Even then there are better ways of handling errors, it simply takes time.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.


    Tuesday, February 21, 2012 4:24 PM
  • You should catch an exception at the lowest level in which you are capable of properly handling the error.  You will only do more harm than good catching an error at a level so low that you don't have any idea what to do in your catch block.  If you can't gracefully continue desipte whatever the error was then you should let the error be thrown up to the next level.  On the other side, if you are capable of handling the error properly then you should do so, rather than letting the remainder of the method crash and leaving "someone else" to clean up the mess.  Sometimes you'll be catching errors at the highest level of your code (oftentimes in these cases you're just logging the fact that you have a fatal error and are crashing) and other times you'll be catching the errors a method call or two above where the happen.

    So what do I mean when I say properly handling the error.  Well, it's hard to say, because it really can vary.  If the error is related to invalid user input, oftentimes the proper way to handle it is to prompt the user for new input.  This means that if you have helper functions, data access layers, etc. dealing with data that at some point came from a user they should NOT try to catch the error, they should just continue tossing it up.  When it gets to the UI layer it will, at some point, be in a position where an appropriate message can be displayed and the user re-prompted for input.  Obviously if you were to continue to let the exception propogate from here the entire form/page/etc. could blow up.

    There are other times where the action that causes an exception is non-critical, so you are capable of continuing on despite the fact that what you were trying to do just didn't work.  This could be because you have planned for the possibility of failure and have an alternate option.  To be more concrete, say there is a configuration value that you fetch from the database.  It's possible, at least for certain values, that if the process fails (connection with the DB is down, for example) that there is a default value that you can use instead.  Other examples might be that a form/page has a number of separate components on it, and no matter what even if component A fails to load component B should still be displayed.  In a case such as this in the code block that adds/initializes component A should catch any errors that might be generated.

    Tuesday, February 21, 2012 6:01 PM
  • In the case of file access - anything can happen really. In this case you should use multiple catches starting with the most specific error to the most general (IOException). As far as I'm concerned the general Exception class should not be used except in conjunction with legacy COM libraries. Even then there are better ways of handling errors, it simply takes time.

    I've never really understood this position.  I have very rarely been in a position in which I was handling different types of exceptions differently.  When it comes to how do I gracefully continue inside of a catch block, I really don't care what type of exception occurred.  What I was trying to do failed.  I generally assume that whatever was in the try block didn't run at all, regardless of the error (other than if there is cleanup that needs to be done) and act accordingly.  It is only from the point of view of logging the error that I care what broke or why, and when it comes to logging all loggers are capable of treating everything as an Exception (unless someone for some reason put additional debugging information in a property that Exception doesn't have).

    If you're going to have exactly the same code in each of the catch blocks, then I don't see what is gained from repeating it several times for each exception.

    Now yes, there are rare instances where certain types of errors are recoverable and others aren't, but I've found those to be rather rare.

    Tuesday, February 21, 2012 6:11 PM
  • What is the proper way of dealing with exception?

    Would you put the try catch block in the most out side loop of the program and catch all errors there to avoid program to crash?

    Another side question:

    How can you make the program stop at the point of error instead of propagate to the most out side try catch block in debug mode?

    When you run the release mode, the program should not stop at the point of error and instead go execute try catch?

    Thanks in advance,

    Proper way of dealing with exceptions: Handle it as early as possible.

    How can you make the program stop.....: This needs a small setting in your VS.

    Goto Debug -> Exceptions and you should see this window. Check the pencil marked checkbox.

    Even cool, go to your thread stack, right click on the last thread which is currently executing and select "Unwind to this frame". VS undoes your exception and you are in debugging mode again.

    In release mode, the program wont stop and go on executing.


    Planet Earth is at risk. Global warming is on a high tide.
    Take Responsibility. Plant Trees. Keep your City Clean and Green.

    Mark all Helping Posts and Close your Threads. Keep the Forum Green.
     - Arun Kumar Allu


    Tuesday, February 21, 2012 6:31 PM
  • In the case of file access - anything can happen really. In this case you should use multiple catches starting with the most specific error to the most general (IOException). As far as I'm concerned the general Exception class should not be used except in conjunction with legacy COM libraries. Even then there are better ways of handling errors, it simply takes time.

    I've never really understood this position.  I have very rarely been in a position in which I was handling different types of exceptions differently.  When it comes to how do I gracefully continue inside of a catch block, I really don't care what type of exception occurred.  What I was trying to do failed.  I generally assume that whatever was in the try block didn't run at all, regardless of the error (other than if there is cleanup that needs to be done) and act accordingly.  It is only from the point of view of logging the error that I care what broke or why, and when it comes to logging all loggers are capable of treating everything as an Exception (unless someone for some reason put additional debugging information in a property that Exception doesn't have).

    If you're going to have exactly the same code in each of the catch blocks, then I don't see what is gained from repeating it several times for each exception.

    Now yes, there are rare instances where certain types of errors are recoverable and others aren't, but I've found those to be rather rare.

     "In this case you should use multiple catches starting with the most specific error to the most general (IOException)."

    I say this because it is standard practice amongst those programmers who have had the good fortune to have read some decent books in their early learning phase, and amongst very highly regarded professional programmers and authors.

    If you expect a certain exception is most likely to occur, put it in the first catch. Put other types of exceptions, in descending order of likelihood of appearance, below that. This will ensure, if you do it correctly, that the error is caught by the exact Exception object designed for it by the good people at Microsoft (or indeed your own custom exceptions).

    Firstly, the exception has a descriptive name, descriptive text, etc., not just a stack trace. This is good for debugging, good all round.

    And you don't have exactly the same code in each catch block - I didn't say that. That would be pointless. You handle a file not found error differently than a permissions error. In the former situation you may ask the user if they have moved the file / do they wish to try again, etc. In the latter situation you may prompt the user to contact their administrator to gain permission, etc.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.


    • Edited by Woohoooo Tuesday, February 21, 2012 6:54 PM
    Tuesday, February 21, 2012 6:53 PM
  • mpt;

      Bet you didn't know you were igniting a flame here...   As it turns out there are two camps to excpetion handling, both are appropriate under the proper setting.  One camp teaches to always handle as low as possible, the other teaches to throw to higher levels. 

    Example:  Let's say you are doing an SQL Query in application code where the user wants a customer based on last name.  The SQL Server throws a SQL level exception that has no meaning to the user.  Do you handle it lower in the code or do you let the user see the SQL Error?  If you handle it lower in the code what message will the user see when that record can't be seen? 

    As Noam pointed out typically you want separate low leve exceptions that are anticipating specific errors in the given context of the program.  For example a FileOpen request is being attempted to a non existing file... There should either be an application check for file exists or an exception handler for FileNotThere...

    From there every application should wrap ALL Exceptions at the EXCEPTION layer otherwise known as the System.Exception layer.  This wrapper will catch all exceptions not thought of and allow the program to gracefully do something. 

    Finally don't over look the importance of proper error messaging, as it is the ONLY way to obtain run-time metrics on the validity of the code.  Some argue that each error thrown should have a unique ID...  By doing it this way you can run reports that answer the question "What's this appilcations' top problems?" 


    JP Cowboy Coders Unite!

    Tuesday, February 21, 2012 7:16 PM
  • If you expect a certain exception is most likely to occur, put it in the first catch. Put other types of exceptions, in descending order of likelihood of appearance, below that.

    I think you mean most specific type down to most general type. If the most general type is the most likely, hence you place it first, it will catch more specific errors so you lose specific handling.


    Regards David R
    ---------------------------------------------------------------
    Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
    Every program eventually becomes rococo, and then rubble. - Alan Perlis
    The only valid measurement of code quality: WTFs/minute.

    Tuesday, February 21, 2012 7:26 PM
  • "I say this because it is standard practice amongst those programmers who have had the good fortune to have read some decent books in their early learning phase, and amongst very highly regarded professional programmers and authors."

    I am of course familiar with the practice.  I have heard it stated on many occasions, often by reputable people.  Nonetheless, in practice, I have found that it is only rarely applicable, and that the reasons supporting this practice tend to either be vague, or only situationally applicable.

    "Firstly, the exception has a descriptive name, descriptive text, etc., not just a stack trace. This is good for debugging, good all round."

    In my experience Exception.Message is sufficent for debugging purposes.  Most messages tend to either contain the name of the exception itself, or are at least sufficient to determine which it is without considerable effort.  So for debugging purposes, as I said before, I tend to log everything as an Exception, and I don't have a different logging utility for each specific type of Exception.

    "And you don't have exactly the same code in each catch block - I didn't say that.  That would be pointless. "

    I know you didn't, I did.  In my experiences it is rare to need different code in different catch blocks, so really what I'm asking is, "How is your code varying between catch blocks?" because while I can come up with situations in which that is the case, they are rare.

    "You handle a file not found error differently than a permissions error. In the former situation you may ask the user if they have moved the file / do they wish to try again, etc. In the latter situation you may prompt the user to contact their administrator to gain permission, etc."

    Both of those errors are things that you can check for before accessing the file (particularly existance).  This means that for the error to occur the file would need to be renamed/deleted/moved or permissions changed after the validation.  Naturally, it is frequently worthwhile to catch the exceptions in these cases, but both cases are rather exceptional.  It is more serious than just a user mis-typing the name or accessing a file they don't have access to.  Those cases are handled via the initial checks.  Since this case really is so exceptional the value in handling them seperately becomes substantially smaller.  In any case, it is just a single example (one that has a fair bit of merrit for being separated out).

    Remeber, I'm not arguing that one should never catch distinct exceptions, merely that it is uncommon to do so, and that catching 'Exception' in my opinion, isn't nearly as problematic as many "best practices" claim.  I'm also not saying that there's anything wrong with separating them out, merely that I fail to see the value added, or why it is so enthusiastically suggested.


    Tuesday, February 21, 2012 7:38 PM
  • If you expect a certain exception is most likely to occur, put it in the first catch. Put other types of exceptions, in descending order of likelihood of appearance, below that.

    I think you mean most specific type down to most general type. If the most general type is the most likely, hence you place it first, it will catch more specific errors so you lose specific handling.

    likelihood of appearence is what is used to determine the order between Exceptions not in the same direct inheritance chain, which in practice tends to be most exceptions you would want to catch (other than when you have a final call to Exception).

    So technically you do both, not just one or the other.

    Tuesday, February 21, 2012 7:59 PM
  • @servy42

    I will do the poor readers a favour and not quote you back! :)

    It is simply my personal paradigm to deal with every single eventuality possible in my code in a proper manner rather than keeping the program running at all costs like some kind of Dalek. You can have multiple catches on the same code (i.e. try, catch most specific, catch second most, etc.). If an exception does occur it will 'fall through' to the exact Exception type, assuming you have accounted for them all. As explained, in this way you can deal with each exception type properly.

    Yes, you can check for the existance of a file before you attempt to perform other operations on it - but that is just one check. What if the user (or anything else) deletes the file before the operation begins? What if the file is locked by another program in the mean time? Simply sticking your desired operations in a try ... catch block with multiple Exception types each dealt with in a relevant way removes the need for manual checks.

    If you do this properly and a situation occurs that you haven't dealt with then the chances are you have failed to account for every eventuality or the environment is so unstable your program will produce unexpected results or will crash anyway. I like my programs to close gracefully before that happens ... programs as undeniably good as the Microsoft Office applications do this. They don't carry on regardless, they do everything they can, they save what they can. If all else fails they inform the user, close down gracefully, restart if possible and allow you to recover your work.

    I once saw an episode of Doctor Who wherein one Dalek got particularly excited and yelled "MAXIMUM EXTERMINATION!!". This catching everything using Exception seems ... a bit mad in exactly the same way to me.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.

    Tuesday, February 21, 2012 8:14 PM
  • "As explained, in this way you can deal with each exception type properly."

    Actually, no, that's what I'm asking you to explain in more detail.  You are saying that you find it useful to handle different exceptions differently.  You gave a singular example of a case in which you would display a different error message to the user depending on the error message.  In theory, one could just use Exception.Message and just display that, but in practice that isn't appropriate for the users of most apps, so your example is appropriate.  I would like you to go more in depth into other situations in which you do different things based on the type of exception caught.  

    "Yes, you can check for the existance of a file before you attempt to perform other operations on it - but that is just one check. What if the user (or anything else) deletes the file before the operation begins? What if the file is locked by another program in the mean time? Simply sticking your desired operations in a try ... catch block with multiple Exception types each dealt with in a relevant way removes the need for manual checks."

    Well, first off, you're adding manual checks in order to remove manual checks.  I don't see how either is significantly different from the other.  If this was my app, I would check first for common issues such as a non existant file, basic permissions, locks, etc.  If any error occured I would tell the user that an unexpected error occured because none of the remaining cases are common in the least, and most of the apps that I work on simply wouldn't need to support such rare cases.  If the users of the app would consider it userful to have different error messages for each of the possible IOExceptions related to reading a file then what you are discussing would be one of the rare instances I've mentioned in which I would consider it appropriate to catch lots of different exceptions.

    "If you do this properly and a situation occurs that you haven't dealt with then the chances are you have failed to account for every eventuality or the environment is so unstable your program will produce unexpected results or will crash anyway. I like my programs to close gracefully before that happens ... programs as undeniably good as the Microsoft Office applications do this. They don't carry on regardless, they do everything they can, they save what they can. If all else fails they inform the user, close down gracefully, restart if possible and allow you to recover your work."

    That's really more related to whether or not you catch any exceptions at all, more so then whether you catch an exception by its specific name or via just 'Exception'.  That said, I imagine there are quite a lot of times that an app like MSWord will catch exceptions and handle them without crashing, often entirely silently to the user (because the exception is in non-critical functionality in which crashing just isn't appropriate).  The question of whether or catch an exception or not is something that I doubt we would disagree strongly on, what confuses me more is the question of how they're handled when they are.

    It's also worth noting that catching an exception doesn't mean you don't crash/stop the application.  In many cases a catch block will just log an exception and then re-throw it, or log an exception and do what is needed to end the program (even if this means not throwing the exception all of the way to the top of the program).  "Handling" many exceptions really is just display an error message and then end the program, I don't think we disagree here, we're disagreeing on the other cases.


    Tuesday, February 21, 2012 9:05 PM
  • I think the main point we disagree on is the issue of rarity. I don't care just how rare an error is - my program should be able to handle it: present an simple, concise error message to the user (not the long-winded .Message value), and carry on running if possible.

    Luckily for us, pretty much every single exception Windows can throw at us in every situaltion has already been considered by the developers at Microsoft. Example:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ExceptionsExample
    {
        class Program
        {
            static int Main(string[] args)
            {
                int num1 = 0, num2 = 0, result = 0;
                bool done = false;
    
                while (!done)
                {
                    try
                    {
                        Console.Write("Please enter an integer: ");
                        num1 = Int32.Parse(Console.ReadLine());
                        Console.Write("Please enter an integer: ");
                        num2 = Int32.Parse(Console.ReadLine());
    
                        result = num1 / num2;                    
                        done = true;
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine("That wan't an integer!");
                    }
                    catch (OverflowException)
                    {
                        Console.WriteLine("The number you entered was too large!");
                    }
                    catch (DivideByZeroException)
                    {
                        Console.WriteLine("Cannot divide by zero - try again fool!!");
                    }
                    catch (OutOfMemoryException)
                    {
                        return -1; // Return failure code and let the system deal with it
                    }
                    catch (ArgumentOutOfRangeException) // Unlikely
                    {
                        Console.WriteLine("That was too large for the console to handle.");
                    }
                    catch (ArgumentNullException) // Something quite serious would have to occur to fire this
                    {
                        Console.WriteLine("An error has occured - please retype the number.");
                    }
                    catch (System.IO.IOException) // Unable to write to the console - this is really bad!!
                    {
                        // Recovery procedure
                    }
                }
                Console.WriteLine("{0} / {1} = {2}\n\nPress Enter to exit...", num1, num2, result);
                Console.ReadKey(false);
                return 0; // Return success code
            }
        }
    }
    

    Here you can see how seemingly the most simple of operations can produce several types of exception, each of which need to be dealt with differently. I encourage anyone to run this code and give it hell!! It's a very, very simple thing to do dividing one number by another. Imagine what you would think if you asked a computer program to do this for you and it failed...

    As I said, in this case I would simply prevent the divide by zero exception rather than catching it. I would also use TryParse rather than catching FormatException and OverflowException.

    There are all kinds of examples I could give you, however this would take rather a long time!! My point is that if you are going to use exception handling instead of hard-coded prevention (which is required sometimes - file and network access are perfect candidates (network access including Internet access of course)) then it should be done like this.

    Without actually coding it I will give you one real-world example:

    You write a program which accesses information contained on an FTP server. There are many exceptions which could be thrown. Maybe your credentials are wrong (you should be given the opportunity to enter them again), maybe the server is busy (the program should automatically retry an number of times before informing the user), maybe the connection is being blocked by your firewall (inform the user and provide instruction as to how to create an exception), maybe the document does not exist, is corrupt, etc., etc., etc.

    Each of these circumstances has been considered by devs at Microsoft and an exception is available for use! They should be used instead of simply throwing up the value of .Message to the user every time something bad happens. It is no use to anyone. If you know precicely what has gone wrong you can take precicely the right action.

    Given these simple examples you should be able to see how the style is applicable to many programs, not just the 'rare' applications you've mentioned. Notice I do not catch Exception at all in the example - it is not required in a release program with proper exception handling and prevention. Such a program would only fail if the system itself failed first. There is not much point knowing whatever Exception's message would tell you if you've done things right because it is entirely outside your control.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.

    Wednesday, February 22, 2012 4:52 PM
  • In the example you provided (just as in your previous example) the only thing you did differently in each catch block was to change the text in what was displayed to the user.  The only reason you are doing this is because for your userbase the exception message isn't an appropriate response, but a detailed error message specific to the error still is.  In my experiences this doesn't come up often.  By design, one ought to be able to just write Exception.Message to the console in your code example.  The reason that you can't is mostly due to your userbase.  

    As you mentioned, in an example like that the few common errors (format, divide by zero) are easily checked for using int.tryparse and an if not zero line.  Since every single other exception is really an exception (as opposed to using Exceptions for expected code paths) it wouldn't really be inappropriate to just write that an unexpected error occured and that the numbers should be re-entered.  For all of the actual exceptional cases they are so rare, and the required user response is the same, so there is no real reason to have distinct error messages printed to the screen (in my mind).

    "Each of these circumstances has been considered by devs at Microsoft and an exception is available for use!  They should be used instead of simply throwing up the value of .Message to the user every time something bad happens."

    I'm not saying that the only thing you'll ever have in a catch block is to print out Exception.Message, that's simply a very common case.  Obviously there are advantages to having different types of exceptions, and situations in which you do want to catch something other than just Exception, so continually responding as if I'm making such claims is counter-productive.

    "It is no use to anyone. If you know precicely what has gone wrong you can take precicely the right action."

    You don't often know that much more when displaying the error message then you do when you throw it.  Is "Cannot divide by zero - try again fool!!" really that much more descriptive than, "Attempted to divide by zero"?  If you take the time to write appropriate error message when throwing exceptions in the first place (this may mean re-throwing exceptions with different error messages in certain circumstances) then you really can frequently catch just a single exception and display its message.

    "Notice I do not catch Exception at all in the example - it is not required in a release program with proper exception handling and prevention. Such a program would only fail if the system itself failed first. There is not much point knowing whatever Exception's message would tell you if you've done things right because it is entirely outside your control."

    If nothing else, catching 'Exception' is useful at the highest level for logging fatal errors.  I wouldn't think you'd dispute that point.

    As mentioned earlier in the thread.  There are also times where you don't want the work done in methodA to cause the program to crash, regardless of what mischief it gets itself into because it's non-critical functionality.  For me it's not a question of if you should catch Exception, but rather when.

    Wednesday, February 22, 2012 6:39 PM
  • I'm going to go for the short[er] answer this time.

    One quote though: "You don't often know that much more when displaying the error message then you do when you throw it.  Is "Cannot divide by zero - try again fool!!" really that much more descriptive than, "Attempted to divide by zero"?"

    I did not think you would take the example quite so literally. It is merely supposed to illustrate a method of exception handling - the messages are in place of much more elaborate code which would deal with real-world situations and exceptions. Such code would probably ping a server, save documents, request permissions from Windows, request lock handles, etc.

    And I rather thought this thread was about how, not if or when you should use exception handling. My theory is quite simple: catch an exception using the appropriate exception type (that's what they're there for) if there is any chance of it occuring; deal with each exception properly; use custom exceptions for your own types rather than rethrowing 'native' exceptions; if an exception occurs that you did not predict ... what is the point of catching it? If you don't know what it is then you probably don't know what to do about it either - let Windows deal with it (Windows is actually quite good so long as programmers don't abuse it).

    And one more quote:

    "If nothing else, catching 'Exception' is useful at the highest level for logging fatal errors.  I wouldn't think you'd dispute that point."

    In alpha/beta stages maybe yes, but by release you should not need it. You should have learned enough about your own program and its environment to deal with every error possible except those outside your control (which you should leave to Windows).


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.



    • Edited by Woohoooo Wednesday, February 22, 2012 9:39 PM
    Wednesday, February 22, 2012 9:33 PM
  • I will add that before I became a programmer myself, or even remotely educated on the subject of computing, the message "An unexpected error occurred ... bla bla bla..." made me think, without fail, 'I wish they had taken the time to expect this.'

    Unless your user base is exclusively computing professionals I would say something like "Methematicians have not yet decided upon the result of dividing by zero. It is either 0 or the dividend. While they decide, please allow me to calculate for you a sum with a positive divisor."

    This is helpful and fun, and may lead the user away from deleting your program and throwing their mouse at the cat for ironic effect.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.


    • Edited by Woohoooo Wednesday, February 22, 2012 9:53 PM
    Wednesday, February 22, 2012 9:51 PM
  • Based on your last two lines it sounds like you're mostly talking about large scale commercial apps being sold to thousands of customers in a retail-style environment.  The vast majority of programming is not in such environments.  Most programs tend to go through that level of exhaustive testing process.  (And even those that do are virtually never flawless.  I don't know about you but I've worked with LOTS of mainstream retail applications that have crashed when performing actions that really oughten't to be fatal errors.  This means that someone, somewhere, didn't consider an exceptional case and handle it accordingly (or the equivilant in another language).  Now I've seen my fair share of problems related to people silently trapping 'Exception' and doing nothing with it.  I agree it can be abused.  My point here is more that there are extremes on both ends.  You shouldn't never catch Exception nor should you always catch Exception.

    "I did not think you would take the example quite so literally. It is merely supposed to illustrate a method of exception handling - the messages are in place of much more elaborate code which would deal with real-world situations and exceptions. Such code would probably ping a server, save documents, request permissions from Windows, request lock handles, etc."

    I was hoping you would provide examples of common situations in which you handle different types of exceptions differently.  So far your primary examples have been all doing the same thing (displaying an error message to a user) with only differences in data that the base level Exception is capable of handling.

    Your FTP example has somewhat more meat on it.  Certain types of errors will result in gracefully quitting, whereas others would result in re-attempting a fixed number of times or re-prompting the user for different inputs.  That is a good example of a case in which you really are doing entirely different things in the catch blocks of different types of exceptions.

    "catch an exception using the appropriate exception type (that's what they're there for)"

    They're there so that you can do it, when you need to.  Just because you can doesn't mean you should.  (Meaning this is not an argument in and of itself.)  By your logic one shouldn't be able to catch a top level exception.

    "if an exception occurs that you did not predict ... what is the point of catching it? If you don't know what it is then you probably don't know what to do about it either"

    That's not strictly true.  You can predict and Exception and still not know what to do with it, and you can assume that no exception could possibly ever be thrown in some block of code and still be able to handle it.

    Let's say that there is some form with data on it and a user presses a button to refresh/sync that data up with a database.  I may not care if the DB is down, if the internet connection is down, if there was a timeout, if there is a lock on the data, or if the database schema was changed and the query won't compile.  I'm still just going to leave the old data there and display some message saying that I was unable to update the data and possibly log the error.  The user doesn't really care which of those errors occured.  I don't even need to spend the time to think about every possible thing that could ever go wrong (it's still a good idea, but it wouldn't change how I would handle the error).  I'm most certainly not going to let the entire program crash just because this bit of functionality isn't working (especially if it's only refreshing a small portion of a larger form).  I also don't want to take the risk that there is some obscrue problem or exceptional situation that I didn't think of that causes the program to crash rather than preventing the users from simply doing the one stand-alone task that isn't working.  This becomes all the more true once you start dealing with version upgrades and the like.  I don't want to have to go through every single catch block in a giant application to re-vet that every single possible exceptional case is handled.  I would miss something, somewhere.

    Wednesday, February 22, 2012 10:03 PM
  • Of course some programmer is going to make some error at some point in a very large application, but as you no doubt know that is the responsibility of your lead developer. They get slapped on the hands.

    Mistakes can be dealt with (again within the code) immediately, assuming the company has the resources.

    And I'm not saying an entire application should close because a particular task has become too difficult. I am saying that the programmer should do everything in his power to deal with errors properly while keeping the operation (CIA-stlye) running smoothly. If something you have not expected occurs, stop in your tracks. Stop whatever you are doing. By all means ask the user if they wish to retry or continue but make sure your program does not cause corruption by continuing after an exception has been caught.

    What I am saying is that you should be quite able, given the exception types that exist within the Framework plus your own derived types, to deal with every possible error individually except those which you cannot do anything about anyway. You leave those to Windows, and the very highly experienced Microsoft staff, to deal with on your behalf.

    If a program crashes fatally on a modern Windows OS, Windows will very intelligently study the situation and offer the user the chance to report the error to Microsoft.


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.



    • Edited by Woohoooo Wednesday, February 22, 2012 10:28 PM
    Wednesday, February 22, 2012 10:26 PM
  • Everyone has their opinions on this one. I'm probably somewhere in between everyone else.

    You should anticipate every possible exception. Write code to avoid it. If that's not possible, catch expected exceptions as close to the site of the exception as reasonably possible if you can provide some sort of graceful behavior. File I/O is a good example - if the file is in use, you may want to quickly catch that exception and just try again. If the file doesn't exist or they don't have permissions, you may want to display a message for the user. In those situations, catch it close to the exception and handle it gracefully.

    If you cannot provide a graceful solution, just don't catch it. At the outer-most level of your application, you may have a try/catch that writes exceptions to a log and just provides a generic "oops, something went wrong" message for users. That should only catch extreme and unpredictable errors, which can't possibly be handled. When those errors occur, a log should be written, admins should be getting emails, red lights should be going off.

    The two most broken rules for exception handling:

    1. Never swallow an error message. If an exception is happening, you either need to deal with it or flag it for someone to track down and deal with later (log message, email, etc)
    2. Never catch an exception if you can't do anything useful with it. If your entire plan is just to show an ugly error message to the user, you may as well let them see the real error.

    In other words, deal with exceptions you can deal with. If you can't deal with them, make sure someone who can is notified when they occur.


    Check out My Blog. Now updated to actually work!

    Wednesday, February 22, 2012 10:28 PM
  • Everyone has their opinions on this one. I'm probably somewhere in between everyone else.

    You should anticipate every possible exception. Write code to avoid it. If that's not possible, catch expected exceptions as close to the site of the exception as reasonably possible if you can provide some sort of graceful behavior. File I/O is a good example - if the file is in use, you may want to quickly catch that exception and just try again. If the file doesn't exist or they don't have permissions, you may want to display a message for the user. In those situations, catch it close to the exception and handle it gracefully.

    If you cannot provide a graceful solution, just don't catch it. At the outer-most level of your application, you may have a try/catch that writes exceptions to a log and just provides a generic "oops, something went wrong" message for users. That should only catch extreme and unpredictable errors, which can't possibly be handled. When those errors occur, a log should be written, admins should be getting emails, red lights should be going off.

    The two most broken rules for exception handling:

    1. Never swallow an error message. If an exception is happening, you either need to deal with it or flag it for someone to track down and deal with later (log message, email, etc)
    2. Never catch an exception if you can't do anything useful with it. If your entire plan is just to show an ugly error message to the user, you may as well let them see the real error.

    In other words, deal with exceptions you can deal with. If you can't deal with them, make sure someone who can is notified when they occur.


    Check out My Blog. Now updated to actually work!

    Well put. I think we finally agree ... except on point 2. You should never give a user who is non-technical a fully detailed error message. Give them a basic, light-hearted, nicely-worded one that will not cause them to become confused and/or hate the programmers or company. 

    If a user phones you - they won't be phoning you but a completely uneducated call centre of course - to report an error and starts by being quite annoyed (not having been able to understand the error message) and saying, 'I got this error see, and it was unexpected apparently...' ... that is the beginning of a BAD phone call. ~30 minutes?

    If a user calls to say, 'I have this message on screen you see, it says the file is locked by Microsoft SharePoint.'

    ...You can simply tell them to close SharePoint or wait until synchronisation has completed. ~3 minutes?


    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.

    Wednesday, February 22, 2012 10:46 PM
  • I think we're on the same page - that's why I clarified "ugly" error message. I've seen a lot of cases where people catch and re-throw exceptions without improving them even remotely. If you're not going to actually do something with the exception or improve it in a meaningful way, don't bother catching it. If you can provide a cleaner and more informative message for the user, then that's definitely worth doing.

    Check out My Blog. Now updated to actually work!

    Wednesday, February 22, 2012 10:50 PM
  • Good show all round I think. I think the OP should buy us coffee whether we're right or not,

    James Finch (MCDST) -- Please vote as helpful if you found this post helpful, or mark as answer if it answered your question.

    Wednesday, February 22, 2012 10:54 PM
  • I knew the op's question would ignite a firestorm.  But I really like how James F. demonstrated excellent technique in the cascading Try Catch.   Most programs today won't do that.  Is it overkill?  For James example yes, but for complex business apps. it's the only way.  No user should ever loose control of the application, which is accomplished by the developer anticipating the proper response to a mistake or two.  The best way to do that is as James demonstrates. 

    I'd like to add one other idea.  At the user layer it is best to issue only unique message identifiers.  The uniqueness is with respect to the entire application.  Reason: It's the only way to get a handle on metrics.  If all errors are logged, a team can become proactive by being able to answer one simple question which is: "During normal production use, what are the top three issues we see".  Unique IDs allow you to answer that question.

    From there... Systems can easily become self-healing...  How many shops are at that point?  MSFT does this by uploading dumps and pushing possible fixes based on specific error signatures.


    JP Cowboy Coders Unite!

    Thursday, February 23, 2012 12:03 AM