Live data from Hacker News

Isaacs: try/catch is an anti-pattern

groups.google.com

1–10 of 140 posts

Re: Isaacs: try/catch is an anti-pattern

#2
I think that having alternatives to try/catch is generally worthwhile. Exceptions should only be thrown in exceptional circumstances.

So (to take some C# code as an example), I'd only call int.parse(myString) if it really, really should only get called when myString contains something that's parseable to an integer.

If it just probably contains an integer, then I'd call int.TryParse(myString, out returnedInt), and check the boolean return to see whether it was valid.

Re: Isaacs: try/catch is an anti-pattern

#4
I never read other people's code. In theory, you could use exceptions for nonunusual events... I've programmed a lot of things and I think I did that just once.

Here's how it is... operator overloading is really neat, but really only helps with matrix math and complex numbers, possibly more. It's only good when it's commonly understood what the operators do. To a noob, lots of things might be like algebra... in fact, only math is like math.

Re: Isaacs: try/catch is an anti-pattern

#5
The problem with try/catch, really, is that it makes a tremendous amount of visual noise, which makes sense for critical operations that might crash everything, but just don't make sense when you can tolerate certain errors or checking for proper output with with a conditional looks better and is more appropiate.

Obviously then you have an issue with language conventions. How do you check for the returns of a method that does an in-place modification without returning anything? What happens when Null is a proper return value? What about having to access specific members or registers to check?

Perhaps, much like logging frameworks, we may need to categorize throwable actions by their importance, or think of a new convention that can handle such things more easily.

Re: Isaacs: try/catch is an anti-pattern

#6
This part really sunk in for me in Bruno Jouhier's reply:

> "So the big mistake I've always seen people make is being too "nervous" about exceptions and feeling that they have to do something about them as close as possible to the point where the exceptions were raised. They need to the exact opposite: feel relaxed about exceptions and let them bubble up."

Hadn't really thought about it in that way, but I find myself employing this pattern where possible - having said that, with async callbacks it can be hard to bubble up when you essentially have multiple logical processes occurring.

Haven't found a solution to this in my own codez yet but I feel a little twitch in my eye whenever I have to do:

    try {
        something = JSON.parse ...
because there's no native `JSON.validate` method.

Not complaining though, definitely not worth losing sleep over .. yet.

Re: Isaacs: try/catch is an anti-pattern

#7
This is the standard in many languages and one that I believe that java got wrong. It was a little rushed with the whole concept of forcing everyone to handle all exceptions concept and building so many exceptions in for silly things like connection failures and parsing errors that reasonably can be expected to happen constantly in the normal runtime of an application.

I follow the rule in almost every language that my app should still be able to run normally if all try catches were remarked out, otherwise I should be handling something better. Exceptions are expensive and don't always back out nicely when they unwind in most languages.

In Objective-C, we play C rules more often then not and almost never use exceptions (except for assertion exceptions). Rather most errors have a ( out NSError ) pointer if they need to pass up errors.

In Python, it's more pythonic to ask for forgiveness than to check before hand so exceptions happen all the time. I'm not sure how I feel about that though but it seems to work well enough.

Re: Isaacs: try/catch is an anti-pattern

#8
Anybody who wants to judge try/catch should first go and read about Common Lisp's condition system. See for example the chapter about conditions and restarts from the excellent book "Practical Common Lisp" by Peter Seibel:

http://www.gigamonkeys.com/book/beyond-exception-handling-co...

Notice I'm not saying you should go and program in Common Lisp, just that you should understand those ideas before you engage in any sort of meaningful discussion about exceptions, errors and error handling in general. Because, you know, some things have already been thought about and invented. Don't re-invent them.

And on a more practical level, in languages with dynamic binding it isn't difficult to provide error handlers and "send" them up the call chain, so that in case of an exception your handler gets called, fixes the problem, and lets the called function continue. You can do all that using try/catch as a low-level tool, I've seen it done in Clojure, using JVM's exception system.

Re: Isaacs: try/catch is an anti-pattern

#9
This seems to be exactly the attitude of Go:

"We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.

Go takes a different approach. For plain error handling, Go's multi-value returns make it easy to report an error without overloading the return value. A canonical error type, coupled with Go's other features, makes error handling pleasant but quite different from that in other languages.

Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function's state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code."

http://golang.org/doc/go_faq.html#exceptions

In Go, if there's a programmer error, call panic(); if there's a non-programmer error, return it as a second return value.

[Added] Plus, it's obvious to see where people ignore errors:

   f, _ := os.Open("filename")
"_" is a throw-away variable to indicate that this value won't be used in the code. It's obvious that the programmer decided to ignore the error.

   f, err := os.Open("filename")
If you don't use "err" later, this won't compile.

   f, err := os.Open("filename")
   if err != nil {
      // handle error
   }
This code handles error.
Post reply on HN