First, the official warning: exceptions in Elixir are not control-flow structures. Instead, Elixir exceptions are intended for things that should never happen in normal operation. That means the database going down or a name server failing to respond could be considered exceptional. Failing to open a configuration file whose name is fixed could be seen as exceptional. However, failing to open a file whose name a user entered is not. (You could anticipate that a user might mistype it every now and then.)
Raise an exception with the raise function. At its simplest, you pass it a string and it generates an exception of type RuntimeError.
| iex> raise "Giving up" |
| ** (RuntimeError) Giving up |
You can also pass the type of the exception, along with other optional attributes. All exceptions implement at least the message attribute.
| iex> raise RuntimeError |
| ** (RuntimeError) runtime error |
| iex> raise RuntimeError, message: "override message" |
| ** (RuntimeError) override message |
You use exceptions far less in Elixir than in other languages—the design philosophy is that errors should propagate back up to an external, supervising process. We’ll cover this when we talk about OTP supervisors.
Elixir has all the usual exception-catching mechanisms. To emphasize how little you should use them, I’ve described them in an appendix.