Hacker News new | ask | show | jobs
by tialaramex 1747 days ago
Does a panic count as "handling" the error?

I actually agree with Rust's choice here. You, the programmer, know whether some particular error is something you can cope with or not and it's appropriate to panic in the latter case. Where you draw the line is up to you, in a ten line demo chances are "the file doesn't exist" is a panic, in your operating system kernel maybe even "the RAM module with that data in it physically went away" is just a condition to cope with and carry on.

My litmus test here is Authenticated Encryption. The obvious and easy design of the decrypt() method for your encryption should make it impossible for a merely careless or incompetent programmer to process an unauthenticated decryption of the ciphertext. This makes most sense if you have an AE cipher mode, but it was already the correct design for both MAC-then-Encrypt or Encrypt-then-MAC years ago, and yet it's common to see APIs that didn't behave this way especially on languages with poor error handling.

In languages with a Sum type Result like Rust, obviously the plaintext is only inside the Ok Result, and so if the Result is an Err you don't have a plaintext to mistakenly process.

In languages with a Product type or Tuple returns like Go, it's still easy to do this correctly, but now it's also easy to mistakenly fill out the plaintext in the error case, and your user may never check the error. Dangerous implementations can thus happen by mistake.

In languages with C-style simple returns, it's hard to do this properly, you're likely using an out-buffer pointer as a parameter, and your user might not check the error return. You need to explicitly clear or poison the buffer on error and even then you're not guaranteed to avoid trouble.

In languages with Exceptions, the good news is that the processing of the bogus plaintext probably doesn't happen, but the bad news is that you're likely now in a poorly tested codepath that isn't otherwise taken, maybe far from the proximate cause of the trouble. Or worse, your user wraps your annoying Exception-triggering decrypt method and repeats one of the above mistakes since they don't have better options.

2 comments

> Does a panic count as "handling" the error?

> You, the programmer, know whether some particular error is something you can cope with or not and it's appropriate to panic in the latter case.

Please don't. I've seen enough libraries whose authors had exactly this mindset; I do not enjoy when some fifth-party dependency thrice-removed, upon encountering an unexpected circumstance, decides that it can't bear to live in this cruel world any more and calls "abort()", killing the entire process: which happens to be a server process, running multiple requests in parallel for which a failure to serve any single request for any reason whatsoever does not warrant aborting all other request.

> Does a panic count as "handling" the error?

Undeniably? Fundamentally the language proposes, the developer disposes[0] and short of Rust being a total language, panics were going to be a thing.

So while one can argue that the ability to panic should not be so prominent, it's certainly an error handling strategy which was going to be used anyway, is perfectly valid (in some situations), and is convenient when you're designing or messing around.

Hell, even ignoring an error is a perfectly valid handling strategy, and indeed pretty easy to implement, just… explicit (though not the most visible sadly, it's much harder to grep a `Result` being ignored than one being unwrapped or expect-ed).

The important bit is that Rust warns you about the error condition(s), and lets you decode on how to handle it.

[0] though there are panicing Rust APIs where it doesn't just propose