3 ms·
The fact that you think that error handling should be ignored is probably what prevents you from seeing the point of the Go error handling. The point is that o
by ainar-g 4y ago
The fact that you think that error handling should be ignored is probably what prevents you from seeing the point of the Go error handling. The point is that one should never only consider the happy path. That one should actually think about how things can fail, what to do about those failures, and how to report those failures with enough context to figure something out on the outside if no appropriate handing is available in the code. Stack traces only give you line numbers. Properly used explicit error handling gives you more context in which a failure occurred.
Here's one example that might make it clearer: https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html https://commandcenter.blogspot.com/2017/12/error-handling-in....
- joshuamorton 4y agoYou can write custom exceptions too. If the only thing you're doing is saying `if err != nil { return nil, err }` anyway, which is what empirically the majority of go's error handling code does, yes, you should have a better way of representing that, whether it's a "?", ASSIGN_OR_RETURN, or exceptions, which take a single character, a single line, or a no characters at all, as opposed to golang's 3 lines of visual noise! Saying that "you can use custom error types to give finer grained error information" is great and all, but I learned that in my CS101 class, in Java, in like 2012. It's not fancy or better or good, except compared to C. Its a worse way of doing a thing that Java and Python (and...) have been doing for decades.
- ainar-g 4y agoOnce again, you're referring to the conditional as “visual noise” as opposed to the actual thing that reminds you that there is a bifurcation here. The point is not to do this: // Bad, most of the time. result, err := foo(x) if err != nil { return err } But to do this: // Better, most of the time. result, err := foo(x) if err != nil { return fmt.Errorf("performing foo on x = %v: %s", x, err) } This isn't noise. This is meaningful logic. That is what exception mechanisms seem to discourage, as they are invisible (unless you wrap every call to everything that throws into a try{}, but then it's not better than an if{} is it?), and this is what the ? operator in some languages discourages as well, because it adds no human- or machine-readable context. There must be syntax that indicates what to do when an error occurs, and that syntax must support addition of information about the context in which the error has occurred. And why not have the most basic conditional take the role of that syntax?
- 8n4vidtmkvmk 4y agoeven if you wrap in try catch its worse because it moves the error to the bottom, messes with your scopes, and you can't tell which line actually threw
- kaba0 4y agoOr — you can wrap logical parts into a try-catch block, because it doesn’t really makes sense to throw 263 different errors for the same logical unit of work. Also, bubbling up is the sane default, even if you are writing a fast script/trying out some code it won’t clutter anything and you will be notified to handle the problems once you want to write robust code. While in Go you will just put empty if errs and will forget about the whole thing, swallowing errors which are arguably the worst thing.
- hdjrudni 4y agoYes, wrapping individual statements is better. But then it's still overly verbose and has weird scoping issues. e.g. in JS you might write: try { let res = somethingThatMightFail(); catch(err) { // log the error or something return null; } // res is good now... but it's out of scope Whereas in C++ you'd just write ASSIGN_OR_RETURN(auto res, somethingThatMightFail()) And it will bubble your error status just like you wanted, only takes 1 line of code, and keeps all the error information (assuming you're using absl::Status). I haven't really used Go, but it sounds like the worst of both worlds. > even if you are writing a fast script/trying out some code it won’t clutter anything and you will be notified to handle the problems once you want to write robust code How are you going to go back and find every callsite that might potentially fail at a later date? There's no easy way to even tell if somethingThatMightFail might fail if it doesn't return something like a "StatusOr" or "Option" or something. I think Java has some tooling to force exception handling. Not sure about Go.
- kaba0 4y agoWell, Java has checked exceptions which have to be handled at call site, or be declared as being thrown in the method handler (making it ‘viral’). I believe these solve this “find every callsite later” thing quite well. While Java’s exceptions are not without problems (too deep inheritance trees don’t make sense on exception types, lambdas not operate too well with this feature, etc), I think it is a really good direction not utilized to the full by any mainstream language.