Elixir Error Handling
Understanding Elixir Errors
Elixir errors, or exceptions, are designed for use in exceptional circumstances, not for regular control flow. They signal that something unexpected has occurred. The Elixir documentation lists built-in errors, such as ArgumentError
, which are crucial for understanding potential issues. These are typically found in the official documentation, often categorized on the left side of reference pages.
Raising Runtime Errors
You can explicitly trigger a runtime error using the raise
keyword. This is useful for signaling a problem that the program cannot recover from gracefully. For instance, raising a simple string will create a RuntimeError
:
> raise "not fabulous enough"
** (RuntimeError) not fabulous enough
To raise a specific error type with a custom message, you can provide the error module and the message:
> raise ArgumentError, "I'm done. We're talking in circles."
#** (ArgumentError) I'm done. We're talking in circles.
Some errors accept specific options that need to be passed as a keyword list. Consulting the source code or documentation for these errors is essential:
> raise KeyError, key: "to car", term: "pocket"
#** (KeyError) key "to car" not found in: "pocket"
Defining Custom Errors
Elixir allows you to define your own custom error types by creating a module that includes the defexception
macro. This enhances code clarity by providing specific error types for domain-specific problems:
defmodule LandWarWithRussiaError do
defexception message: "Never."
end
> raise LandWarWithRussiaError
#** (LandWarWithRussiaError) Never.
Rescuing Errors
The try/rescue
construct allows you to catch and handle specific errors that occur within a block of code. This is a way to manage exceptional situations and prevent them from crashing the entire application. You can specify which error types to rescue:
try do
if false do
raise "are we there yet?"
else
raise ArgumentError, "I'll pull this car around!"
end
rescue
e in RuntimeError -> IO.puts "No!"
e in ArgumentError -> IO.puts "That's it we're going home!"
end
Important Note: While try/rescue
is available, Elixir offers more idiomatic ways to control program flow, such as using pattern matching, `case` statements, and return tuples (e.g., {:ok, value}
or {:error, reason}
). Errors should be reserved for truly exceptional and unexpected situations.