(no title)
jamamp | 9 months ago
This is where languages diverge. Many languages use exceptions to throw the error until someone explicitly catches it and you have a stack trace of sorts. This might tell you where the error was thrown but doesn't provide a lot of helpful insight all of the time. In Go, I like how I can have some options that I always must choose from when writing code:
1. Ignore the error and proceed onward (`foo, _ := doSomething()`)
2. Handle the error by ending early, but provide no meaningful information (`return nil, err`)
3. Handle the error by returning early with helpful context (return a general wrapped error)
4. Handle the error by interpreting the error we received and branching differently on it. Perhaps our database couldn't find a row to alter, so our service layer must return a not found error which gets reflected in our API as a 404. Perhaps our idempotent deletion function encountered a not found error, and interprets that as a success.
In Go 2, or another language, I think the only changes I'd like to see are a `Result<Value, Failure>` type as opposed to nillable tuples (a la Rust/Swift), along with better-typed and enumerated error types as opposed to always using `error` directly to help with error type discoverability and enumeration.
This would fit well for Go 2 (or a new language) because adding Result types on top of Go 1's entrenched idiomatic tuple returns adds multiple ways to do the same thing, which creates confusion and division on Go 1 code.
barrkel|9 months ago
A policy of handling errors usually ends up turning into a policy of wrapping errors and returning them up the stack instead. A lot of busywork.
XorNot|9 months ago
billmcneale|9 months ago
And this is exactly where Go fails, because it allows you to completely ignore the error, which will lead to a crash.
I'm a bit baffled that you correctly identified that this is a requirement to produce robust software and yet, you like Go's error handling approach...
haiku2077|9 months ago
Note that ignoring errors doesn't necessarily lead ti a crash; there are plenty of functions where an error won't ever happen in practice, either because preconditions are checked by the program before the function call or because the function's implementation has changed and the error return is vestigal.
pphysch|9 months ago
No it won't. It could lead to a crash or some other nasty bug, but this is absolutely not a fact you can design around, because it's not always true.
stock_toaster|9 months ago
[1]: https://borgo-lang.github.io/ | https://github.com/borgo-lang/borgo
ignoramous|9 months ago
LinXitoW|9 months ago
Hell, you can mostly replicate Gos "error handling" in any language with generics and probably end up with nicer code.
If your answer is "JavaScript" or "Python", well, that's the common pattern.
jamamp|9 months ago
Whereas in Go, the error is visible everywhere. As a developer I see its path more easily since it's always there, and so I have a better mind to handle it right there.
Additionally, it's less easy to group errors together. A try/catch with multiple throwable functions catches an error...which function threw it though? If you want to actually handle an error, I'd prefer handling it from a particular function and not guessing which it came from.
Java with type-checked exceptions is nice. I wish Swift did that a bit better.