Debugging Phoenix with IEx.pry

Previous Posts in this series

Brandon Richey
Oct 12, 2015 · 8 min read

Writing a Blog Engine in Phoenix and Elixir, Part 1

Writing a Blog Engine in Phoenix and Elixir, Part 2: Authorization

Current Versions

As of the time of writing this, the current versions of our applications are:

  • Elixir: v1.1.1
  • Phoenix: v1.1.0
  • Ecto: v1.1.0
  • Comeonin: v2.0.0

If you are reading this and these are not the latest, let me know and I’ll update this tutorial accordingly.


Often in development you end up with a need to interact with a part of your application mid-stream, whether to understand some strange behavior a little better or to mess around with some properties/view context and state/etc. Elixir provides us a nice little toy for doing precisely this and it’s very compatible with Phoenix! If you’re a Ruby developer messing around in the Elixir ecosystem, you may especially be missing tools like pry and byebug, but we get something even better here!


We’ll create a new Phoenix application to use as our stomping ground for this. I’m feeling particularly unoriginal today, so I’ll just call it “debug”.

Answer “y” to installing brunch dependencies. We’ll then follow the rest some of the instructions and do our own thing when it comes to starting up the server:

The last command is the most important one: we need to run mix phoenix.server inside the context of an iex shell. Without that, we will not be able to reach out to the shell to debug things.

We have everything we need to be able to mess around with things, so we’ll start off simple and throw some debugging into our controller. Let’s visit http://localhost:4000/ and make sure the Phoenix starting page shows up before we continue!

Debugging a Controller

We’ll start off by opening up web/controllers/page_controller.ex since that comes default with every Phoenix application. When we open it up by default we see:

Let’s make it possible to debug from our index action. At the top, we’re going to add the following line before our defmodule Debug.PageController do line:

Next, inside of our index function, we’re going to add the following line:

And then we refresh our browser. We should see the following output in our terminal window:

We’ll answer “Y” here to get into the interactive debugger. Now, we’re in the context of that function call, so we can start to mess around with things. If params was actually being passed, we could inspect it. conn is being passed in and not thrown out, so let’s inspect that:

We can also access the help on any modules (or for iex in general) using h(). For example, if we just type in h (calling the h function with no arguments), it’ll print out the information for IEx and how to use it. However, you can also feed it a module name and it will give you the documentation for that module. Try it with h(Ecto.Repo) and h(Phoenix.HTML) as tests!

There’s a ton of information here that you now have access to. This is great for poking around at things and learning how things work in general. If we had an Ecto model that we were displaying to a user, for example, here we could attempt a query and look for something that was failing or bad data or anything like that.

If we want to exit out of our debugging window, we have a few options. The first is that we can just Ctrl+C twice to exit the entire shell and give up, but that’s rarely what we want to do! Instead, if you type in respawn() in the pry window, it will continue on with the rest of the request as if you had never initiated the debugger in the first place.

Debugging a View

Debugging a view is basically identical to debugging a controller. If we were to add a new function to our View and call it from the template, we could get dumped there into an IEx pry session. We’d have to modify the code for web/views/page_view.ex to:

Notice we added the require IEx line and the IEx.pry line to this file. Then inside of our template web/templates/page/index.html.eex we add the following call somewhere:

Which dumps us into an IEx.pry window. We can inspect the value of the message variable that we created in the function, for example. You can probably see why this is very very helpful!

Debugging a Template

Inside of a template, we can either require IEx right in the template or we can do it inside of the view that the template is using instead (which is what I personally prefer; I don’t like lots of code hanging out inside of my templates). Still, we can write something like this:

And then inside of our pry window, do this:

Debugging a Model

We’ll need to create a model really quick to be able to test this out. We’ll just create a simple User model with a single string field, username.

Restart the server first and then we’ll jump into web/models/user.ex and toss require IEx at the top. We’ll then modify our changeset function and toss IEx.pry at the top of the function. Finally, we’ll go back into our controller web/controllers/page_controller.ex and ensure that we call the changeset function to trigger this debug window. Modify the index action to read as follows:

Refresh our browser window and you should see our familiar prompt:

We’ll answer Y and now we should be inside of our changeset function. We’ll see what we get for our model object and what we get for our params:

We’ll type in respawn() and carry on our merry way!

Debugging in Tests

The last neat thing we can do with an IEx window is inside of our tests. Open up test/controllers/page_controller_test.exs and add our require statement and pry statements:

To run our tests, the command gets a little more complicated. The command that we need to run to make this all work is:

Again, we’re just using our normal command to run things but we’re doing so inside of an IEx context (thus the iex -S bit). We’re also adding the — trace option here because if we don’t, the tests will time out automatically and we don’t want that! Beyond that, this is just inside of the context of the test that we threw this command into, so we can inspect conn, for example.

There you go! You now know how to debug your way into each portion of your Phoenix stack now!

Brandon Richey

Written by

I am a software engineer, and now, published author! Check out my new book at