Cutting to the chase: rescue/1 and catch/1 (rescue and catch with one parameter) handle different types of errors; to handle all kinds of errors use catch/2 (the version of catch with two parameters) .

See the GitHub README for complete examples, and there is additional information in the docs.

Error handling (aka exception handling) in Elixir often manifests itself with the try and rescue keywords, which correspond to errors that are triggered using raise/1 and raise/2. But in addition to raise there are other functions for triggering errors:

  • throw/1
  • exit/1
  • :erlang.error/1

(Talking about what each of these are for is…

Writing an assert_invalid macro for ExUnit assertions. Implementation at the bottom.

I was working a lot with Ecto Changesets - using them for validation in my HTTP application. The application code (the code in my lib/ folder) was very nice, but I was not happy with the verbosity of the tests. Each test looked something like this:

An example without my custom assertion

This was okay for a single test about a single field, but quickly lead to a tonne of copy-and-paste across multiple tests that were asserting on multiple fields.

The solution was to create a custom assertion that…

ETS will hold references to large binaries, even if just part of the original binary is stored in a table. Copy binaries if pieces of them are going to be kept around for a long time.

I was creating a new Elixir application that was part of a larger micro service. It was responsible for consuming messages from Kafka, decoding the payloads, plucking two fields from the payload, and storing those fields in an ETS table. Disregarding the boilerplate and error handling, the code looked like this:

A callback which eventually gets call by Brod to handle Kafka messages. Looks simple, but there is a memory leak here!

I ran the code locally, wrote some unit tests, and everything worked as…

# Add to shell profile
export ERL_AFLAGS="-kernel shell_history enabled"

The ERL_AFLAGS variable is for setting a list of options which are added to the beginning of the erl command. In this case, we are adding the shell_history option for saving our shell history between sessions.

Note that “shell” here means either iex or erl, and if you use both, you’ll notice that the history is shared between them.

An example of IEx history. Use the up and down arrows to navigate the history.

The default number of bytes of history that are saved is 512KB. For my day-to-day work (where I am often copying large Elixir maps and structs from the logs and playing with…

The handle_continue/2 callback prevents race conditions and allows for faster, asynchronous initialization.

Let’s start by looking at the problems that handle_continue solves. If you don’t care about the problems and just want the code, you can skip to the end or checkout (pun intended) the GitHub repo.

Here is a short, all-in-one example that shows an application which starts three instances of a process, each of which load different data when they start up:

An application with three processes which are started synchronously, one after another.

The supervisor iterates through its list of children, calling each child’s init/1 callback. This…

Wrap your return values in tuples so you can clearly match them in the else block

The with expression allows us to declare clauses and their expected results. The clauses are executed in order until the end of the list, or until one clause doesn’t match with its expected result. Here is the example from the Elixir documentation:

A simple `with` expression

In this example, we are calculating the area of a rectangle. If everything works out we will return {:ok, area}, if not, we will fall through to the else block and return the error tuple {:error, :wrong_data}.


Using inets and httpd to create a simple HTTP server without adding external dependencies

Recently I needed to add a healthcheck endpoint to an application that was solely responsbile for reading and writing to Kafka. Normally when I am creating an HTTP application I would reach for Cowboy or Phoenix, however, this use case was very simple: I just needed a single endpoint that would return 200 OK once the application was up and running and was healthy.

Before adding a new external library to our application, lets review what is given to us “for free”. It is well known…

This is a post about how Elixir knows the difference between Erlang modules, Elixir modules, and Elixir atoms

If you have ever come across Elixir code that calls an Erlang module, you will know it looks something like this:

IEx screenshot using an Erlang module

However, normal atoms that are declared in Elixir code don’t get functions, so how does Elixir know the difference between them?

If we open up IEx and create some atoms, there appears to be no difference between the :os atom and the :tyler atom. …

Sometimes I come across code where an map (or tuple) is being tested against a pattern to return a boolean result; like this:

An example of pattern matching with a case statement to return a boolean result

That works fine, but can be simplified by using the Kernel.match?/2 function:

An example of pattern matching with Kernel.match?/2 to return a boolean result

Like when using other (more famous)Kernel functions such as ==/2, to_string/1, and send/2, the "Kernel" prefix can be omitted leaving us with a clean one-line statement.

Here is a silly “real-world” example which shows that you can also use guard clauses in your match expression:

An example with a guard clause

Lastly, if you are just testing for one (or maybe two) conditions in a map, keep things simple and stick with a simple Map.get/3 :

An example of keeping things simple and not using pattern matching

This is a post about what supervisors do (part 1), and how to build your own example supervisor that can restart dying processes (part 2).

Part 0: New Mix Project

To follow along and run the examples in iex, create a new project to hold the code for our worker and supervisor:

mix new my_supervisor

Part 1: What do supervisors do?

To help understand what supervisors do, and why you might want to use them, lets take a look at some silly, unsupervised Elixir code that receives messages and parses those messages as integers:

lib/Parser.ex: A flakey worker that tries to parse all incoming messages as integers

Note: we call our…

Tyler Pachal

Software engineer at PagerDuty, working with Scala and Elixir.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store