Best Practises for Error handling elixir?

Generally it is exactly right. You should only handle returns from a function which you actually can handle. Please don’t program defensively.

You can see {:ok, res} = my_fun() as an assertion which should never fail. (or a failure you can’t do anything about anyway). And if it does fail, the supervisors make sure your application doesn’t crash.

If {error, reason} is something you need to handle in your business logic you deal with it with pattern matching and you should only deal with the errors you care about. Because it is part of business logic you have to deal with is so the “complexity” is unavoidable.

Don’t catch errors and log anywhere except the top level of your code. It is better to bubble up. Error messages should ideally be tuples of atoms with as much information as possible so that you clearly know which sort of errors to handle and which to ignore.

A nice “pattern” in erlang applications is to return atoms {:error, :some_error} and then have the module returning the error being able to format it into a readable string. This means you can bubble up the error message as a tuple and only the code doing the logging translate it to human readable format. It also means the module producing the error is able to give a meaningful message rather than the caller having to make something up.

case MyModule.my_fun() do
  {:ok, res} -> :working_good
  {:error, :some_error} -> {:error, :some_error}
end

and in top level handling code:

case x of
  {:error, reason} -> Logger.log(MyModule.format_error(reason))
end
2 Likes