8

When is it best to use try and catch? I've gotten angry responses when I answered questions using try and catch (some even -1 me...) I Googled it and found this article and also this stackoverflow question.

I give some examples:

  1. I have a drop down list with time zone IDs, when the user selects his time zone I'm updating the database. In other application i'm pulling this the value from the DB and recalculate the user current time and date. There is an option that the data in the DB is misspelled (hardcoded change in the DB or bug). In the conversion method of the date time of the user I'm using try and catch, which some people told me it is wrong!. I could check the value from the DB using for loop but it is costing more for each time I'm converting the date time...

  2. I have to declare if an XML file is well formatted using this code:

    protected bool IsValidXML(string xmlFile)
    {
        try
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlFile);
        }
        catch(XmlException ex)
        {
            ///write to logger
            return false;
        }
        return true;
    }
    

    I can't see any other way to check the xml file.

  3. Sometime I have a part on my application I'm writing to a file. writing to a file can cause exeprtion for many reasons , some other process is using this file while writing or other. so usually I'm using this code:

     using (StreamWriter w = new StreamWriter(fs))
     {
         try
         {
             w.Write("** (Line) " + someValue + " **" + Environment.NewLine);                       
             w.Flush();                       
         }
         catch(IOExeption ex){}
         finally
         {
             w.Close();   
         }
     }
    

In conclusion I see some ways to use try and catch and ways to not use. The one sentence in the article I saw said If an exception happens, you need to know about it. , but when dealing with a generic application most of the times I know that an exception will happened but most of the times I can't really know why it happened so I can't catch it before (like the examples I wrote) , So when is best to use the try and catch

In the same level in ASP.NET the page has an Error event that you can catch like so:

this.Error += new EventHandler(Page_Error); //this = instance of System.Web.UI.Page

Is the event is the same as try catch problem??

Community
  • 1
  • 1
Izikon
  • 902
  • 11
  • 23
  • 1
    What question? Because it really depends on the question at hand. – BoltClock Oct 28 '13 at 15:40
  • Number 3) The catch is useless. It's empty. – Arran Oct 28 '13 at 15:40
  • 1
    @BoltClock That [-1 answer is here](http://stackoverflow.com/a/19635625/2530848) and am the person who voted down. – Sriram Sakthivel Oct 28 '13 at 15:43
  • 1
    @SriramSakthivel - you see, that's why I love you, you are persistence – Izikon Oct 28 '13 at 15:45
  • Case 2: [Validate](http://msdn.microsoft.com/en-us/library/hdf992b8.aspx) the XML first. – mbeckish Oct 28 '13 at 15:46
  • +1 I like your approach for asking it as a question about this man. You'll get definitely a good answer – Sriram Sakthivel Oct 28 '13 at 15:47
  • @mbeckish - It sounds like it's gonna cost more.. – Izikon Oct 28 '13 at 15:47
  • It seems you've deleted that answer. You could have got opinions about that if you have not deleted that – Sriram Sakthivel Oct 28 '13 at 15:49
  • @mbeckish You can't validate a XML if it's malformed. If you want to know if e.g. a string or a file is a well formed/syntactically correct XML, using a simple try/catch is the best approach. – sloth Oct 28 '13 at 15:50
  • There is lots and lots and lots of information on this subject out there. Way too much for a single SO question. If you want to know how to properly use exceptions go pick up some books, take some classes at a university, do some research through the many blog posts and online tutorials on the subject. The question simply isn't specific enough for an SO answer to cover it. – Servy Oct 28 '13 at 15:55
  • @SriramSakthivel - I know but this answer didn't help him anyway so... (BTW I +1 to the other thing....) – Izikon Oct 28 '13 at 15:55
  • 1
    @Servy - I'm trying to get a day by day programmers opinion. – Izikon Oct 28 '13 at 15:56
  • 2
    @Izikon Which is not what SO is here for. Highly opinion based questions are not well suited for this site's format, and as such they are not allowed. – Servy Oct 28 '13 at 15:57

6 Answers6

4

How you handle an exception depends on the nature of the exception, and on the context in which it occurs.

Smart people have written excellent articles about the subject, and I certainly can recommend:

About your examples:

In case 1 you might indeed want to be defensive. But then make sure that you do something sensible in that catch block.

Case 2 looks reasonable, but you're reading the XML document only to throw it away. Would it no make more sense to also process it?

In Case 3 you are using try finally, which is definitely not the same thing as try catch. In your specific example you don't even need it, as the using statment is already making sure the file will be closed.

Kris Vandermotten
  • 10,111
  • 38
  • 49
1

From a personal perspective I've always assumed that whatever can go wrong, will go wrong and write my exception handling strategy accordingly. One of my major bugbears with others code is when you get an unhandled exception that could easily have been trapped - it looks messy an if it is production code then it shows a complete lack of knowledge of how your program works and the things that might go wrong.

My approach might be overkill, but if something you are doing can throw an error then it should be trapped. I'm not a huge fan of letting exceptions cascade through the stack and being caught at the top level - I'd prefer to trap them at source, log them and then, if the application allows it continue, or at worst fail gracefully and leave the user (or other developers) understanding what has gone wrong or why.

With web applications we use a slightly different approach. The error (stack trace etc) is logged, so that authorised people can see it and the user is given a cut-down version of the error which tells them something has gone wrong but not the specifics.

Thats my two pence anyway. I'm not sure if the approach is right or wrong, but it works for us and helps us to produce more robust code.

Andrew
  • 2,315
  • 3
  • 27
  • 42
  • 3
    The only exception (haha) I have to this approach is there are times when letting an exception pop up through your code can be acceptable. I see no reason in these cases to create a cascading catch/rethrow chain. – Logarr Oct 28 '13 at 15:51
  • 1
    I don't entirely agree with this answer. Don't catch exceptions in code that can't do anything about them. They should bubble up to where they can be handled appropriately, either with a graceful fail or a retry or whatever. Of course, perhaps you meant this and I misunderstood. – siride Oct 28 '13 at 16:12
  • I think I'd disagree with your disagreement! If an error is raised for example in my data layer I want to trap it there. I admittedly can't do much about it, but I need the state of my data objects for detailed logging which will be gone as soon as it leaves the method. – Andrew Oct 28 '13 at 17:34
1

The criticisms of your use of try/catch in this answer were not against using try/catch in general, but against that particular way of using it.

  • You should capture the exception object (i.e. use catch(SomethingHappenedException e) so you get the available information about what went wrong.

  • You should catch specific exceptions rather than everything. In the DateTime example, I would try to find what exceptions might be thrown by each of my calls. I would then try and figure out if there was some way of trapping these errors without using exceptions - one of the exceptions that might be caught in that code is a ArgumentNullException. That's an exception, but I should be able to handle that within the flow by first checking that I'm not passing a null zone id.
    Finally, if it's not possible to handle those cases within the normal flow of the program, I catch specific exceptions that might plausibly occur, and as closely to the source of the exception as possible.

It might seem a bit more effort but it does save you on debugging time down the road!

Community
  • 1
  • 1
Joel Rein
  • 3,608
  • 1
  • 26
  • 32
1

For example 1, it would be helpful to see code. It's hard to comment without a more concrete idea of what you're doing.

For example 2, the problem with that code is that it completely hides any error condition. Sure, we'll find out if an xml file is good or bad... but why is the xml good or bad? We can't know. It's not that try/catch is bad: it's that the whole thing is being written at the wrong level. Just write code to read the xml file, and have your error handling around that code.

For example 3, you are again swallowing any helpful exception information, and in fact not doing anything with your try/catch at all. The .Close() call in your finally blocks is completely unecessary, because closing your stream is entirely handled when the stream is disposed by the using block.

In summary, I think what you need to learn here is not that try/catch blocks are bad. It's that swallowing exception information is bad.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • I read in articles and other place about eating or swallowing exceptions. I know it maybe a bad diet, but what you and the article mean by saying eating or swallowing? – Izikon Oct 28 '13 at 16:03
  • Swallowing an exception means to catch it, and then ignore any information in the exception or stack trace. That's bad. If you're tempted to swallow an exception, it's likely that your handling the error at the wrong level. Go up, and place the try/catch around where you called the current function. – Joel Coehoorn Oct 28 '13 at 16:04
  • so if i use in example 2 only catch not catch(IOExeption) is better? – Izikon Oct 28 '13 at 16:05
  • 1
    No. Go back to the principle of catching at a higher level. You want to move the exception handling to call site for your function. In this case, it seems to make no sense, in that it completely invalidates the method. When that happens, you're doing the error checking in the wrong place. Instead of a separate method to check whether the xml is well-formed, _just try to parse the file already_. Let the error handling for a well-formedness error go in the same place as error handling for other kinds of errors while reading the file. – Joel Coehoorn Oct 28 '13 at 16:08
0

I think I can sum up the issues people have had in the past with your questions on try...catch, as well as provide some clarity that should help you in the future.

Your first two examples are caused by data validation errors. The data should be checked for known validation errors before being passed to the conversion function (example 1) or trying to write an XML file (example 2).

There is significant overhead in exception handling, so it should only occur when absolutely necessary. The try...catch pattern is designed for handling unexpected (exceptional) errors, not standard data validation.

Example 3 is almost proper usage. It is a situation where there are unexpected things that may occur that you cannot be prepared for, like an IOException. Catching a specific exception is considered bad form as it can lead to multiple catch blocks or missed handling. Catching the generic Exception object is better, and the exception handling code can determine and deal with the exact type of exception.

Your try...catch block should encapsulate the streamwriter as well, since it is best practice to only have one try...catch per method. If you use try...catch, it must always contain exception handling code. Empty catch blocks or empty finalize blocks are bad form and are not helping the code or anyone who is trying to maintain it after you.

    try
    {
       using (StreamWriter w = new StreamWriter(fs))
       {

           w.Write("** (Line) " + someValue + " **" + Environment.NewLine);                       
           w.Flush();                       
       }
    }
    catch(Exception ex)
    {
        //exception handling code here
    }
    finally
    {
       //any clean up code here. The using statement makes it unnecessary for the streamwriter
    }

Hope all of this helps answer some questions and bring some clarity to the issue.

Nick Zimmerman
  • 1,471
  • 11
  • 11
0

In my experience, any external operations (such as interacting with a db or file system, or using 3rd party components) should have a try catch block around it. In my own code, I always try to put in guard clauses to methods to limit the number of exceptions my own code produces, if for example you know that the database won't accept a null First name on a person object, add a guard clause should be added to the top of any save method.

In short, don't rely on exceptions to tell you where your code is going wrong, rather try to cut down the likelyhood of an exception first

monkeymatic
  • 131
  • 9