Watch out for "possible" errors



  • I was investigating a database error in our logs and wondering why it was being masked as a "Parse exception".   So I looked in the code and found this:

            final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
            try{
                Date date = dateFormat.parse(dateFormat.format(Calendar.getInstance().getTime()));
                return myDao.findSchedulesForDay(date);
            }
            catch(Exception e){
                log.error("Parse Exception when passing date for schedule lookup");
                return null;
            }

    I suggested to the developer that he improve the error handling here so that a SQL exception thrown by the DAO would not be logged as a "Parse Exception" with no stack trace.  Here's his "improved" code:

            final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
            try{
                Date date = dateFormat.parse(dateFormat.format(Calendar.getInstance().getTime()));
                return myDao.findSchedulesForDay(date);
            }
            catch(Exception e){
                log.error("Possible parse Exception when passing date for schedule lookup"+e);
                return null;
            }

    Wow.  And while I was busy worrying about the error handling, I hadn't even noticed the bigger abomination: the solution he has chosen for getting "today's date"....



  • I'm almost at the point where I think it would be worthwhile to write a book entirely devoted to the subject of telling Java programmers to stop catching Throwable, Exception and RuntimeException.

    For the record, returning null instead of propagating the exception is a WTF as well.   You can solve your problem by having him take out the try/catch entirely and declare the method to throw SQLException.

    As for getting the current date, it looks like he's never read the javadoc for Date.  Does he know it exists?



  • @VGR said:

    As for getting the current date, it looks like he's never read the javadoc for Date.  Does he know it exists?

    I actually do this quite a bit. It can be useful when doing date based calculations within an application and the date/time must match precisely with the date/time on the database server. Usually this would probably be embedded within one SQL query, but I can see a use for a function call like this.

    As for overriding the try/catch, you may want to hide the fact that you're obtaining the date from an SQL Server Query. Not sure how exception handling works in Java, but they should really be throwing another exception (probably a generic exception)



  • Um, it's not as funny if I have to spell it out, but you guys seem to be missing the point.  I'm not trying to debate about how best to throw/catch exceptions in Java.  I am marveling at the fact that he considers it an improvement to add the word "Possible" to the error message.  It reminds me of another developer I used to work with who was told by Ops to stop having the web app return a 404 when it was really a server error, not a "page not found".  So the guy "fixed" it by changing the text of his 404 message to read "This may mean that a database error occurred, that the operation timed out, or that our CEO just got hit by a bus."  I'm paraphrasing there, but it was something ridiculous like that.

    Regarding the date thing, it did turn out that he needed to truncate the time portion of the date, which explains (but does not really pardon) the use of the date formatter. We cleaned this up by simply using trunc() in the SQL query.
     



  • @DaEagle said:

    @VGR said:

    As for getting the current date, it looks like he's never read the javadoc for Date.  Does he know it exists?

    I actually do this quite a bit. It can be useful when doing date based calculations within an application and the date/time must match precisely with the date/time on the database server. Usually this would probably be embedded within one SQL query, but I can see a use for a function call like this.

    As for overriding the try/catch, you may want to hide the fact that you're obtaining the date from an SQL Server Query. Not sure how exception handling works in Java, but they should really be throwing another exception (probably a generic exception)

    But he's not retrieving the date from the DB server, he's constructing it in Java with the following:

     Date date = dateFormat.parse(dateFormat.format(Calendar.getInstance().getTime()));

    when he could just as well do:

    Date date = new Date();

    which constructs a Date representing the current system time.

     

    As for the exception, he ought to be throwing a custom one appropriate for the layer that the code is part of, so something like DAOException or DataException or similar. Failing that, as the poster implies, swallowing the original exception and reporting an error that may be entirely unrelated to the actual problem is an absolute no-no; if he must construct the date like that, he should use two try/catch blocks, or reword the message to be much more generic and include the original Exception. Catching Exception is generally not correct behaviour either...



  • @averagejoe said:

    Um, it's not as funny if I have to spell it out, but you guys seem to be missing the point.  I'm not trying to debate about how best to throw/catch exceptions in Java.  I am marveling at the fact that he considers it an improvement to add the word "Possible" to the error message.

    I know, but it's more fun to discuss (and promote) good coding practices than to rail on some inept programmer for having tunnel vision. But yes, the fact that the guy "fixed" it by not fixing it is a big WTF for sure. I've run into that situation more than once and it's very frustrating. If he doesn't know that 'catch Exception' is bad, though, it probably will never occur to him to change it.



  • IMO Java is to blame in part here. Although you can use exceptions correctly in Java, the checked exception system encourages catching without throwing.

    AFAIK there are three solutions to Sun's WTF without declaring exceptions, each of them being somewhat WTF themselves:

    <FONT size=2>
    • Re-throw the exception using sun.misc.Unsafe.getUnsafe().throwException() [not portable to non-Sun JVM]
    • Re-throw the exception wrapped by RunTimeException [makes exception handling later on more painful]
    • Modify the compiler to disable checked exceptions (i suppose this should be easy now that the compiler is GPL) [makes program incompatible with default compilers]

    Fortunately i can use C# most of the time, but for the poor souls forced to use Java, the third solution, especially when implemented by Sun, would make their lives much more pleasant and their WTF's less numerous.

    </FONT>


  • IYO Java is to blame... for the programmer using a completely inappropriate method (that can theoretically fail) to obtain a Date representing today, when a method (that can't theoretically) fail not only exists but was right under his nose?  And for then writing completely inappropriate exception-handling code?

    Yeah, whatever.

    Checked exceptions aren't a WTF if you don't get in the habit of writing methods with poor cohesion.  If you disagree with how Java would like you to code, that's fine; there's certainly many other ways that work just as well, if not better.  That doesn't make the "Java way" wrong or WTFy.
     



  • @anonymous2 said:

    IMO Java is to blame in part here. Although you can use exceptions correctly in Java, the checked exception system encourages catching without throwing.

    AFAIK there are three solutions to Sun's WTF without declaring exceptions, each of them being somewhat WTF themselves:

    <FONT size="2">
    • Re-throw the exception using sun.misc.Unsafe.getUnsafe().throwException() [not portable to non-Sun JVM]
    • Re-throw the exception wrapped by RunTimeException [makes exception handling later on more painful]
    • Modify the compiler to disable checked exceptions (i suppose this should be easy now that the compiler is GPL) [makes program incompatible with default compilers]

    Fortunately i can use C# most of the time, but for the poor souls forced to use Java, the third solution, especially when implemented by Sun, would make their lives much more pleasant and their WTF's less numerous.

    </FONT>


    I wrote a long, rambling rant to respond to your argument, but I realized that I was getting well off base.

    Sun isn't to blame here. No way, no how. Exceptions are Exceptional Things; they should be considered during design and dealt with by the programmer. Your advocacy of either throwing program-killing runtime exceptions or swallowing them whole is beyond the absurd. If the system prompts the user for an integer, and the user enters "173x", the system shouldn't barf and die; it should say "Oops, that didn't quite parse, try again!" and get another value. Methods should enumerate exceptions that they may throw so that calling methods know what to look out for, and what to consider, not just because Gosling was Exception Happy when he sat down to write the language.

    Honestly, if your response to non-fatal exceptions is "kill it with fire and salt the earth it grew in" then I shudder to think of what your code must be like. Fortunately, I'll always be able to beat your implementation of Tic-tac-toe by choosing square #10, or better yet kicking it up a notch to 11.



  • I agree that exceptions are exceptional things and should be used only in exceptional situations. This is why i think an integer parsing function should only throw exceptions in exceptional situations, such as running out of memory. Invalid input should be  reported in the return value. IMO the right interface for this function looks like this:

    bool tryParseInt(string s, out int result)

    This avoids exceptions in non-exceptional situations entirely.

    There are many situations in which Java declares exceptions which i know that they can never happen in my specific case. If such an exception does occur it would be truly exceptional and i would like it to be handled by a generic exception handler somewhere, which reports it to the user and which may or may not terminate the application. I would not want to ignore such an exception on the spot using try{}catch{} as this destroys the purpose of exceptions (many people seem to do this in a way that kills all exceptions). I would also not like to include this (irrelevant) exception in all method signatures up to this handler.

    All in all, checked exceptions were a design mistake made by Sun. This can also be seen by the fact that relevant Java clones (i.e. C#) do not copy it.



  • C# is not a java clone, it's more like a VB clone with java syntax.

    C# exists for the sole purpose of being popular and letting Microsoft gain financial control over developers who would otherwise have been using java. It is not a shining example of the height of modern language design. Lack of checks like this does not help produce better software - quite the opposite. But it does make lazy developers happier, so it makes the language more popular.

    Java's exception checking is flawed in a number of respects and nowhere near powerful enough - but you can't handwave it off as a design mistake just because one language, which wasn't even intended to be "good design", did not duplicate it.
     



  • In return for eliminating exceptions your "tryParse" pattern would introduce a complete second argument-passing mechanism to Java, which currently has exactly one of them (pass by value).  I'm not at all convinced that's a net win; pass by reference can make code much harder to read as information can leave a function in yet another way.  It also makes flow analysis for checking for unitialized variables either more complex (non-local to the variable's declaring scope) or more stupid (forcing you to initialize variables that get immediately overwritten by another method).

    And anyways, your example doesn't match the problem: NumberFormatException is unchecked (derives from RuntimeException by way of IllegalArgumentException) and you can skip the try/catch or throws for it if you "know" it can't happen.  Why that decision wasn't carried through to DateFormat#parse(String) and friends, I don't know -- ParseException is derived from Exception directly and is therefore a checked exception, so the language does force you to handle it one way or another (even with "assert (CANT_HAPPEN)", which I hate).  If you're certain it can never happen, rethrowing it wrapped in a RuntimeException may be appropriate.  They're used for indicating programming, rather than environmental, errors normally anyways.



  • @asuffield said:

    C# exists for the sole purpose of being popular and letting Microsoft gain financial control over developers who would otherwise have been using java.

    Java has a purpose, too: to attract the dangerously psychotic developers, so we know where they are and can keep them away from the interns.

     



  • @VGR said:

    I'm almost at the point where I think it would be worthwhile to write a book entirely devoted to the subject of telling Java programmers to stop catching Throwable, Exception and RuntimeException.

    I agree with this, as a Java programmer I caught Throwable and Exception early in my training only. I never do that anymore. I don't know why anyone would catch RuntimeException, thats stupid, RuntimeExceptions are thrown (if used properly) only by programming error (logic error?), why would you catch something you did wrong.

     Unfortunatly I see this type of coding all over the place.



  • I don't know if Java has this in some way (I use C#), but C# has the concept of nullable types. For example, the type int? can be set to null unlike the normal int type. If Java has a similar mechanism, what if you had a method like this:

    int? tryParseInt(string s)

    where Java would return null if s couldn't be parsed.



  • @csi235 said:

    I don't know if Java has this in some way (I use C#), but C# has the concept of nullable types. For example, the type int? can be set to null unlike the normal int type. If Java has a similar mechanism, what if you had a method like this:

    int? tryParseInt(string s)

    where Java would return null if s couldn't be parsed.

     

    You could use an Integer, which can be assigned null. And if you're on Tiger, you get auto-boxing/unboxing with that so it wouldn't be too bad. 


Log in to reply