| 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. |
> 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.