3 Exceptions vs. other patterns of handling errors in your code

 

This chapter covers

  • The best patterns for handling exceptions
  • Exceptions from third-party libraries
  • Exceptions in multithreaded and async code
  • Exceptions in functional and object-oriented programs

Errors and exceptions are inevitable in our code. Almost every code path fails if something unexpected happens. Imagine that you are executing a simple addition of two numbers. At first glance, such a code path cannot fail. However, you need to be aware that your program executes in some context. For example, you may get an out of memory error if there is not enough memory to run any operation on your machine. You may get an interrupted exception in the multithreaded context if your code is executed in a separate thread, and this thread gets the interruption signal. Many potential problems can occur.

Most often, our code is not trivial, and it can fail in a variety of ways. Handling failures should be our first thought when creating our code. Our code should be fault-tolerant, meaning that it should recover from problems whenever possible. Before you can decide how to handle exceptions, you need to design an API that tackles problems and signals them in an explicit way. However, if we signal the possibility of every error explicitly, our code would become hard to read and maintain.

3.1 Hierarchy of exceptions

3.1.1 Catch-all vs. a more granular approach to handling errors

3.2 Best patterns to handle exceptions in the code that you own

3.2.1 Handling checked exceptions in a public API

3.2.2 Handling unchecked exceptions in a public API

3.3 Anti-patterns in exception handling

3.3.1 Closing resources in case of an error

3.3.2 Anti-pattern of using exceptions to control application flow

3.4 Exceptions from third-party libraries

3.5 Exceptions in multithread environments

3.5.1 Exceptions in an async workflow with a promise API

3.6 Functional approach to handling errors with Try

3.6.1 Using Try in production code

3.6.2 Mixing Try with code that throws an exception