4 ms·
That creates some mostly unnecessary boilerplate. I.e., if an error happens down the stack in function to read config, which calls a function to parse a file, w
by drdaeman 12y ago
That creates some mostly unnecessary boilerplate. I.e., if an error happens down the stack in function to read config, which calls a function to parse a file, which calls a function to read a file, you'll have to either propagate (or otherwise handle) that `err` manually or lose the precious information.
On the contrary, Java-like pattern of functions like `Config readConfig() throws IOError, ParseError` simplifies code quite a bit. No need to deal with IOError in parseConfig - if an exception happens there it'll be propagated automatically. And `throws` clause allows for static checking and warning whenever you forgot to handle something. And sane code analysis tools would also warn you whenever you really wanted overly-broad `catch Exception(e)`, too.
There's a panic/recover in Go, but they aren't serious. At least, to my limited knowledge of Go, there are no guidelines on using them properly, so everyone panics with whatever they fancy, and this lack of conventions is a bit problematic, like `raise "Failed to open file"` in Python.
- RBerenguel 12y agoThe standard is usually if err != nil { return (whatever null type), err } The error will propagate up, since all calls to a function returning err should be checking for the err. In a not-so-ideal world, just return err up. In a relatively more sane world, you can send "up" extra information along the error (just creating a new error with extra info) to know the error path. The first caller will/should handle this error then.
- moreentropy 12y agoOTOH, if you follow Go's idioms and handle every error where it happens, your code will look like having a lot of boilerplate at first, but you end up with better error handling. It's the same as putting a try-except catchall around every single call in python, because in python you can never be sure (without reading the source) what kind of exceptions something will throw. For request based services and something where some big ass operation will either fail in some way (and i don't care where exactly) or be successful, exceptions are fine. If something goes wrong somewhere, log it and reply with HTTP 500. But for servers with data i care about, i most likely want to recover right where the error happened, and actively decide if i want to abort and push the error to the next layer. Not having exceptions makes this more intuitive.
- pekk 12y agoYou shouldn't be putting a try-except catchall around every single call in Python. Exceptions mean you don't have to do that.
- moreentropy 12y agoFor me the most important thing exceptions mean is that they might pop up at any time, with unpredictable types. So as long as I don't have a catch all exception handler wrapped around all code, it might crash at some point.
- TheLoneWolfling 12y agoAssuming you're talking about unchecked exceptions, correct.
- moreentropy 12y agoPython doesn't have checked exceptions.
- moreentropy 12y agoThis one really deserved downvoting, great job whoever did that :/
- bsdetector 12y ago> if you ... handle every error where it happens This is what the debate is about: "if". The problem with Go's error handling is that people don't handle every error. And due to poor documentation structure and returning one error type, often you have to even go digging through source code to just find out what the specific error values can be and under what conditions they occur, which makes it easy to write code that you think handles all error conditions but in fact does not. The code on the golang web site didn't even check the error code from println and you never see this done in code. If you point this out you're met with "why would you want to check that error?", which is a tacit admission that Go programs will always have missing error handling and that "if" in "if you handle every error" is never met in reality. In contrast to this there are no Java programs that don't IOException from a failed println, and yes even println can matter. Redirecting output with ">&-" is different from ">/dev/null".
- zimbatm 12y agoThe readConfig example is not really an issue in go. Just return the io error and type switch after the readConfig. if config, err := readConfig(ioReader); err != nil { switch err.(type) { case io.ErrClosedPipe: // do one thing case ParseError: // do something else case ... } }
- drdaeman 12y ago> Just return the io error Manually, on every function call that may fail - that was my only point why exceptions may result in a clearer code. section, err := parseSection(ioReader) if err != nil { return nil, err } Has some boilerplate, as compared to a typical exception-based section = parseSection(reader) // throws IOError
- zimbatm 12y agoYeah I get what you mean. If you forget that "throws" comment then the Java code is opaque to the exception. I think Go developer see a value in having errors exposed explicitly, it forces them to think about how to handle them instead of having a catch-all at the top of the program. But now we're down to philosophy and personal taste :)
- Iftheshoefits 12y agoI don't consider error handling to be unnecessary, but it is boilerplate, no matter how or where it's implemented. That's because every non-trivial program has the potential to enter an error state. That state can either be ignored (deliberately or not, the latter case being a major source of most of the angst and misconceptions around C and C++) if the language allows it or handled in some way, and that way is by boilerplate "if/else" or "try/catch".
- dragonwriter 12y ago> There's a panic/recover in Go, but they aren't serious. They are very serious. > At least, to my limited knowledge of Go, there are no guidelines on using them properly, so everyone panics with whatever they fancy, and this lack of conventions is a bit problematic, like `raise "Failed to open file"` in Python. The convention is that you don't let panics escape across the public API of your function -- which also makes most other cross-project conventions for panics unnecessary. Its probably useful to have internal conventions within a project for internal consistency, but since none of your panics should ever escape across a public API boundary, a broader convention would have limited benefit.