4 Errors

 

This chapter covers

  • The distinction between errors a system can recover from and those it cannot recover from
  • Failing fast and failing loudly
  • Different techniques for signaling errors and considerations for choosing which to use

The environment in which our code runs tends to be imperfect: users will provide invalid inputs, external systems will go down, and our code and other code around it will often contain some number of bugs. Given this, errors are inevitable; things can and will go wrong, and as a result we can’t write robust and reliable code without thinking carefully about error cases. When thinking about errors, it’s often useful to distinguish between errors from which a piece of software might want to recover and those from which there is no sensible way to recover. This chapter starts by exploring this distinction before exploring techniques we can use to ensure that errors don’t go unnoticed and that they’re handled appropriately.

4.1 Recoverability

4.1.1 Errors that can be recovered from

4.1.2 Errors that cannot be recovered from

4.1.3 Often only the caller knows if an error can be recovered from

4.1.4 Make callers aware of errors they might want to recover from

4.2 Robustness vs. failure

4.2.1 Fail fast

4.2.2 Fail loudly

4.2.3 Scope of recoverability

4.2.4 Don’t hide errors

4.3 Ways of signaling errors

4.3.1 Recap: Exceptions

4.3.2 Explicit: Checked exceptions

4.3.3 Implicit: Unchecked exceptions

4.3.4 Explicit: Nullable return type

4.3.5 Explicit: Result return type

4.3.6 Explicit: Outcome return type