4 ms·
> Go has no exceptions. I'm not a fan of the verbosity of error handling with exceptions either. It is particularly bad for fine grained error handling. Howe
by sbov 15y ago
> Go has no exceptions.
I'm not a fan of the verbosity of error handling with exceptions either. It is particularly bad for fine grained error handling.
However, I do like that the default state of a non-handled error is to propagate and eventually crash the thing rather than continue with errors that may subtly corrupt things. I haven't used Go, but from the explanation of error handling Go seems to do the latter rather than the former (please correct me if I'm wrong).
In most languages, exception handling doesn't seem designed for fine grained error handling, which makes one not want to use it for that. Rather than complain about the verbosity of their methods, why not try to fix the issue with a less verbose method?
E.g. something like: handle := openSomeFile() catch err
Or ignore it if you want, letting it automatically propagate: handle := openSomeFile()
- Jabbles 15y agoGo has "panic", which does as you suggest and propagates up the stack to something that can "recover". If nothing can, it will crash the program. Its use is generally reserved for truly exceptional circumstances. Most errors are handled quite like the way you propose, e.g. handle, err := Open(). You can ignore the error if you wish, but that's up to you, and it's explicit that you're ignoring it: handle, _ := Open(). Panics are not meant to be a way to control the flow of the program, but rather to regain control of it if something disastrous occurs.
- casualsuperman2 15y agoIn Go, the accepted way to report errors is to take advantage of multiple returns, such as: result, err := somePotentiallyFailingFunction() if err != nil { // Try to recover here ... // Not recoverable? panic() } And this call to panic works the way you prefer. Note that doing the following: result := somePotentiallyFailingFunction() won't compile since the number of values on the left doesn't match the right, so if a function can fail and returns an error, you will know. If you do something like: result, err := somePotentiallyFailingFunction() And then never check err, it's actually a compile-time error, which enforces error checking, to a point. What's next is the kind of thing you don't like, and it's poor style. result, _ := somePotentiallyFailingFunction() This assigns the error to _, which causes no errors if you don't use it. Hope this clears some things up.
- klon 15y agoOk but exceptions also give you alot of context about the error like exactly where it occured. How is that handled in Go?
- dhconnelly 15y agoDo you mean that exceptions, when they bring down your program, indicate the line where the exception was thrown? If so, then `panic` in Go does the same thing. Using goroutines and panic/recover, you can do the same things you do with try/catch/throw.
- barrkel 15y agoNo; the point is that the information is contextual. For a database failure, the information will be DB specific; for an IO failure, IO specific; for an IO failure in the DB subsystem, it will be information about IO failure wrapped in info about the DB failure. I think too many people get wrong idea about exceptions from defaults in many environments. Exceptions being thrown should not normally be a sign of a bug; knowing the line number the exception thrown should be irrelevant information almost all the time, save for errors like access violations or null pointer exceptions. Instead, the information contained in an exception can usually be turned into actionable data to a user or administrator of an app (depending on whether it's on the client or server).
- ericbb 15y agoThe error type is an interface. You can return values that contain contextual information as long as the error value you return has an Error() method returning a string. type ParseError struct { line int } func (e ParseError) Error() string { return "Parse error at line: " + fmt.Sprint(e.line) } Note: The current release may vary slightly on the details. I'm using a pre-release build. But older versions are similar.
- casualsuperman2 15y agoAnd then in the code for handling the error, you can do switch err.(type) { case db.IOError: // Database exception here case io.FileNotFoundError: // File exception default: // Pass it to our caller for them to handle. return nil, err } Which gives you the ability to selectively catch errors based on type.
- canop_fr 15y agoA related proposal to simplify "default" error rethrowing : http://canop.org/blog/?p=195 http://canop.org/blog/?p=195