Hacker News new | ask | show | jobs
by solatic 1864 days ago
> It really makes you think about the appropriate response to this specific failure.

I beg to differ. It forces you think about whether but not why the function itself has failed. The "why" is embedded in the type of the error (or exception) itself, but Go does not force you to examine the type of the error; indeed, sheer muscle memory compels you most of the time to just write if err != nil again and again.

> I can decide how to gracefully fall back if a failure occurs before I'm even allowed to use the successful result.

You could wrap every line of Java code in a try/catch if you wanted to (it wouldn't be idiomatic, but it's definitely possible). You're just not forced to.

For what it's worth, you also shouldn't email your ops team directly from production code. It doesn't scale. You should log the error, and your monitoring stack should handle altering the relevant team (full disclosure: I work for such a monitoring stack company). It's very rare that you actually want to recover from errors, as that's typically a pattern that leads to silent failures and difficult to diagnose issues.

1 comments

Yeah, I'm not endorsing Go's approach to errors, just the idea of errors as values. I can't speak for Go, but other languages make it very obvious that to handle an error you have to inspect its type, and thereby get at the "why".

The lack of forcing to handle (checked) exceptions is exactly why I dislike Java's model. Until I've checked for an error state, I want to have an Either that may or may not have the data I'm looking for (and if it doesn't, has an explanation). In a truly exceptional situation I can crash and give a 500 error, but checked exceptions are by definition supposed to be recoverable, and in a production codebase I don't want to be able to lazily avoid recovering from them.

You're differentiating between Java the language and Java the ecosystem. Java's tooling is so strong that you can use static analysis tooling to fail builds that throw checked exceptions, if you want. See e.g. https://rules.sonarsource.com/java/RSPEC-1162
That… sounds like exactly the opposite of what GP wants? If you can’t throw checked exceptions then you can only throw unchecked exceptions, whose catching and checking is even less enforced by the compiler.
GP is differentiating between library code and application code. You wouldn't turn on the static analysis to fail the build on checked exceptions in library code, since you want to force the application to keep track of known error modes in libraries and decide where it's appropriate to handle them. But you would turn them on in application code in order to prevent application code from using exceptions-as-control-flow, which is an anti-pattern and one of the reasons why people who value Go's error handling sometimes hold their opinions because of scarring they suffered from anti-patterns that were in Java codebases they worked with.