6 ms·
Next on the list: error handling. Which is absolutely not a problem, and works very very very well as is. Then again, one can hope that maybe by 2025 :) https:
by alquemist 6y ago
Next on the list: error handling. Which is absolutely not a problem, and works very very very well as is. Then again, one can hope that maybe by 2025 :)
https://github.com/golang/go/issues/32437 https://github.com/golang/go/issues/32437
https://github.com/golang/go/issues/32437#issuecomment-512035919 https://github.com/golang/go/issues/32437#issuecomment-51203...
https://github.com/golang/go/labels/error-handling https://github.com/golang/go/labels/error-handling
- jhoechtl 6y agoNo, error handling is not the best. The lake of generics seems to get addressed with lots of pondering which is a good thing. But error handling is just awkward. I do not mean the retval, err := funccall(a,b) syntax but rather the absence of a standardized way to get stack traces.
- alquemist 6y agoIt's really a joke :) Fundamentally, the Go team made the correct choice between explicit and implicit error handling. Yet one would hope for a bit terser syntax and language supported stack traces, 11 years after launch. For a good overview of the issue: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md https://go.googlesource.com/proposal/+/master/design/go2draf....
- mseepgood 6y ago> Yet one would hope for a bit terser syntax and language supported stack traces, 11 years after launch. The Go team tried, but the community shot it down. Your link was the first proposal, and this was the second proposal: https://github.com/golang/proposal/blob/master/design/32437-try-builtin.md https://github.com/golang/proposal/blob/master/design/32437-...
- Groxx 6y agoAs one who didn't like either proposal: I'm thrilled that they were shot down. Both worked fine (great, even) in simple cases, but fell apart when needing to add context / wrapping to multiple possible errors. Simple cases are already simple. It's the harder spots that need help.
- alquemist 6y agoCan you please share some examples of the harder spots?
- Groxx 6y agoBoth have at least one shared issue which makes 2+ error wrapping noisy or nasty: func whatev() (err error) { defer helper(&err, "mightFail context to help debugging", some, vars) try(mightFail()) defer helper(&err, "alsoMightFail context to help debugging", some, vars) try(alsoMightFail()) } if the second call fails, your error has now been wrapped twice. There are of course ways to deal with this. You can add a "already wrapped" sentinel of some kind (say, a * bool that they check and modify), or use a `helper := once(helperfn)` to do that same kind of thing internally... but that's more verbose. And can't be done generically without reflection (though `func(*error, string, ...interface{})` would be quite common, which might be good enough). Inline handlers shown in many examples are even worse since they can't be composed as easily, so you'd probably end up maintaining a bool var between all handlers. By hand. They both also require naming your `error` return value, which requires naming all returned values, which has been a depressingly large source of shadowing and not-initialized-value mistakes in my experience. Improperly-initialized values especially, as those tend to cause problems a fair distance from the cause, and sometimes go unnoticed for quite a while. tl;dr it adds more easily-forgotten boilerplate to non-trivial error handling, and makes it and related code more mistake-prone. I'd rather have `return fmt.Errorf(err, ...)`, it fairly naturally resists growing more complex as your func grows more complex.
- alquemist 6y agoThanks, appreciated. Your example rhymes with u/jhoechtl remark that there is no standardized way to manage stack traces, aka stacked error contexts. Perhaps the Golang elves will come up with an elegant solution. By 2025 :)
- fourseventy 6y agoMy opinion on this is not popular but I absolutely love the way go handles errors. I love that errors are returned by functions and then immediately handled. I prefer it to the try/catch paradigm where the error is maybe handled somewhere up the call stack
- alquemist 6y agoGranted, explicit error handling is a good idea. At some level, it depends on the personal style. Perhaps I'm missing something, but I like to write a ton of assertions to validate code invariants. On assertion failure, which obviously never happens as I write perfect code that never violates invariants, all I want to happen is 'write the error in the logs and return 50x'. I suppose panic/recover is the way to go, but I have the impression they are shunned by the community and not recommended by Golang official docs. https://golang.org/doc/faq#assertions https://golang.org/doc/faq#assertions > Why does Go not have assertions? > Go doesn't provide assertions. They are undeniably convenient, but our experience has been that programmers use them as a crutch to avoid thinking about proper error handling and reporting. Proper error handling means that servers continue to operate instead of crashing after a non-fatal error. Proper error reporting means that errors are direct and to the point, saving the programmer from interpreting a large crash trace. Precise errors are particularly important when the programmer seeing the errors is not familiar with the code. > We understand that this is a point of contention. There are many things in the Go language and libraries that differ from modern practices, simply because we feel it's sometimes worth trying a different approach.
- Smaug123 6y agoWell, the point is not that "handle errors immediately" is bad. It's that "tuples are a poor way to do it". A Result type makes you handle errors immediately, but also precisely models what you need (i.e. you don't even get the choice to use an invalid returned value).