Handling errors and managing exceptions
We already approached the let it crash mantra. We saw in the previous two recipes how an Elixir system is able to deal with failures in processes and keep running.
Defensive programming is not encouraged at all by the principles that guide languages such as Elixir or Erlang. Even if we aren't writing defensively, it is still a good idea to control what happens when errors occur. Supervisors allow us to write code that keeps breaking and crashing and yet recovers from the crash. We will mainly find two categories of errors after compiling our code (compilation errors are outside this equation): runtime errors and logic errors. The former are easier to deal with, while the latter may become more difficult to reason and track.
Note
In distributed systems, a whole set of problems may rise due to race conditions, timing issues, network unreliability, and so on.
To track and solve this category of errors, we benefit from the ability to debug live systems via...