Hacker News new | ask | show | jobs
by riyadparvez 1522 days ago
This reminds me of Dan Luu post about outages and post-mortems [1]:

> For more on this, Ding Yuan et al. have a great paper and talk: Simple Testing Can Prevent Most Critical Failures: An Analysis of Production Failures in Distributed Data-Intensive Systems. The paper is basically what it says on the tin. The authors define a critical failure as something that can take down a whole cluster or cause data corruption, and then look at a couple hundred bugs in Cassandra, HBase, HDFS, MapReduce, and Redis, to find 48 critical failures. They then look at the causes of those failures and find that most bugs were due to bad error handling. 92% of those failures are actually from errors that are handled incorrectly.

[1] https://danluu.com/postmortem-lessons/

1 comments

I believe this, but I don't think it addresses whether implicit or explicit error handling is more likely to result in correctly handled errors. My opinion is that explicit is better than implicit (and I'm using implicit and explicit loosely here--the `?` operator is technically explicit, but I'm considering it to be implicit since it's easy to overlook a single character).
It's impossible to overlook that single character because your code won't compile otherwise. Unlike Go, you cannot accidentally ignore an error condition in Rust. There is no way to discard the error without explicitly doing so, and even then you still have to decide on a non-error return value to return (because Rust functions that fail provide an error or a value and not both, unlike fallible golang functions).

People who believe Golang is explicit and hard to ignore errors but think that Rust is implicit and easy to ignore errors have never used both languages, full stop.

I challenge you to provide me with an example of Rust code that ignores an error without explicitly and obviously doing so.

I felt the same way about Go until I've tried using it in a large corporate setting. The linters will absolutely scream at you if you ignore the returned error, and you will need to comment //nolint to silence it which immediately attracts the reviewers attention. The net result is that errors are basically impossible to ignore in Go as well.

If you're writing alone in a vacuum without linters, then I agree that Rust is more explicit.

I have accidentally failed to handle errors in golang code in a large corporate setting that was run under multiple linters. This was "simple" and straightforward code, and the last time it happened was within the past month. I wish I remembered exactly what I did, but it was rebased over to be fixed.

If you need sufficiently advanced linters to catch every case, your error handling is not explicit. Especially if those linters are not currently sufficiently advanced.

> If you need sufficiently advanced linters to catch every case, your error handling is not explicit.

You're conflating "explicit" and "statically verified".

Agreed that static verification by default is ideal. Rust wins here.

> It's impossible to overlook that single character because your code won't compile otherwise

I was thinking about the case where there is a `?` in the code but the reader glossed over it, thinking it didn't return an error.

> Unlike Go, you cannot accidentally ignore an error condition in Rust.

There is no way to discard the error without explicitly doing so, and even then you still have to decide on a non-error return value to return (because Rust functions that fail provide an error or a value and not both, unlike fallible golang functions). I agree, I think Rust is strictly better in this capacity.

> People who believe Golang is explicit and hard to ignore errors but think that Rust is implicit and easy to ignore errors have never used both languages, full stop. I challenge you to provide me with an example of Rust code that ignores an error without explicitly and obviously doing so.

You seem to be unduly defensive. This was never my claim. I have used and enjoy Rust. We're all friends here :)

> I was thinking about the case where there is a `?` in the code but the reader glossed over it, thinking it didn't return an error.

The error is explicitly in the function prototype. Every code path that returns must ensure the result is an `Ok(T)` or an `Err(E)`. You just can't accidentally overlook this. Even if you do gloss over it when skimming, the error is handled and dealt with.

> You seem to be unduly defensive. This was never my claim. I have used and enjoy Rust. We're all friends here :)

I'm just tired of hearing that Golang's error syntax is explicit but Rust's is somehow implicit because it's fewer characters, even if they desugar to virtually exactly the same thing. Both are explicit. Golang's is verbose and (ironically) error-prone.

> The error is explicitly in the function prototype. Every code path that returns must ensure the result is an `Ok(T)` or an `Err(E)`. You just can't accidentally overlook this. Even if you do gloss over it when skimming, the error is handled and dealt with.

Some of us are mere mortals. We tire and make mistakes. Perhaps even unworthy of the mantle of "Rust programmer".

> I'm just tired of hearing that Golang's error syntax is explicit but Rust's is somehow implicit because it's fewer characters, even if they desugar to virtually exactly the same thing. Both are explicit. Golang's is verbose and (ironically) error-prone.

I already admitted sympathy to the viewpoint that Rust's error handling is technically explicit, and that Go's error handling would be improved by static verification that errors are handled. What more do you want from me?