5 ms·
I haven't used Go or Rust seriously, but have written some Go toy code. This part of your post struck a nerve with me. I modified it slightly, to relate to Go
by prirun 5y ago
I haven't used Go or Rust seriously, but have written some Go toy code. This part of your post struck a nerve with me. I modified it slightly, to relate to Go's error handling, for me at least:
> often it's not worth taking on that burden just to theoretically handle cases that rarely occur and even more rarely cause any problem. Programming is a means to an end, and the cost of [Edit] adding if err != nil to every line of code [/Edit] (increased development time) is often not worth it.
I basically like Go, I really want to like Go, but as a Python person who has used exceptions with good success for 13 years in HashBackup, I can't see myself adding an if test to practically every line of Python code, just to catch an exception that might occur once in a blue moon.
A lot of software is not so mission critical that lives depend on it. If that is the case, sure - add error checking to every line of code. But for a lot of software, IMO, it's too much work for too little reward. If something blows up in production in an unexpected way, sometimes that's okay. You log the problem, fix it, and it's fine.
I re-read the Go error handling page before posting, because maybe it's not as bad as I had initially thought. Nope, still looks pretty cryptic to me:
https://go.dev/blog/error-handling-and-go https://go.dev/blog/error-handling-and-go
- layer8 5y ago> If something blows up in production The problem is if it doesn’t quickly blow up, but instead silently corrupts data or causes other problems down the line that are hard to backtrack to that specific missing check.
- prirun 5y agoBut because exceptions bubble up the stack frame, there can be no missing checks. I'm not suggesting things be coded as: try: do something except Exception, err: pass If a piece of code is has a try/except, then it's because there is the expectation that it might fail and certain kinds of failures can be handled. If a failure is not one of the expected failures, then do a raise and let the exception go higher up. It's either going to hit a handler in the main program or will exit to command level. In either case there's a stack trace to see where the problem occurred. Exceptions tell you exactly where things blew up, whereas the "if err return" paradigm only does that if the test at each level adds identifying information. I've seen some Go stack traces. Talk about hard to backtrack: the ones I've seen go on and on. I understand it's because there are multple Goroutines running and each one has a stack trace, but they look pretty daunting to me.
- layer8 5y agoI was responding to your scenario of having to “add error checking to every line of code” due to the absence of an exception mechanism, and your assertion that “it's too much work for too little reward”. My point was that in that situation (no exception mechanism available) it’s often irresponsible to not do that work, because the possible consequences are unpredictable. I fully agree that having an exception mechanism is the way to go, so that adding error checks every other line isn’t necessary anymore.
- j3s 5y ago> If something blows up in production in an unexpected way, sometimes that's okay. You log the problem, fix it, and it's fine. as the person on call for such events, it's really not fine. would you rather handle these errors upfront during development time or unexpectedly and uncontrollably, during runtime? having been on-call in one way or another for ~10 years, i know which i'd prefer. after having used golang in production, i will never go back to using a dynamically typed language if i can avoid it. almost 0 thought or effort is required to handle errors correctly in go, and it's still possible to ignore them (just use `_`). not that i'd recommend ever doing that.
- kaba0 5y agoIt’s a big assumption that you can even handle the error at the callsite, or that you will actually handle it correctly there, or just write some low-effort attempt because the overall picture is more important for now, but later on you won’t notice how it is not correct and it will just silently fail. Exceptions are in my honest opinion better on every single front. Checked exceptions would be the panacea but Java’s version is not the best due to subclassing. But overall bubbling up exceptions is the correct thing to do — in most cases a problem can’t be meaningfully handled at the call site. Let’s say you want to read from a file during a HTTP request but the read fails n methods deep. There can be any number of other error occurrences and the only sane choice here would be to return some error code to the web client requesting the site. Why do you want to handle it n times instead of only at the goal?
- AnimalMuppet 5y agoBut people write "low-effort attempts" at exception handlers all the time. So using exceptions instead of error values doesn't actually change the situation.
- kaba0 5y agoDefaults matter. Exceptions give me the question whether I want to worry about this piece of code here, or just go on and be reminded that it is actually important at runtime with an unmissable runtime error which has exact character number for the origin of the mistake. Even Java’s checked exceptions can be just added to the method signature. (Ab)using Result types without good syntax for dealing with the very common case of “handle it higher up” (Rust’s ? macro is ok, not perfect but it is a much better compromise) is coming from a wrong angle imo.