My debugging experience when working in the Elixir codebase

ervinismu
pengenpaham
Published in
4 min readDec 18, 2022

--

Photo by Ariana Suárez on Unsplash

When developing application, sometimes we need to debug the code we have written. In this article, i will share my debugging experience when working in Elixir codebase, especially when working with Elixir and Phoenix web framework.

My Elixir and Phoenix versions :

  • Phoenix ~> 1.6.15
  • Elixir ~> 1.12

🗒 : I’m still new in the Elixir ecosystem, I wrote this article based on the lessons I learned when I started working with the phoenix web framework.

Before We Start : Use Case

I’ve created a Phoenix app with basic features (ex : login, register, logout). In this article we’ll try to debug registration flow. The purpose of this debugging is to see the submitted data from the register page when filling out the form and clicking the REGISTER button.

http://localhost:4000/users/register

1 - IO.puts

This includes integers, strings and atoms. You can use string interpolation in IO.puts with #{}. For example, IO.puts “user email is #{user_params[“email”]}”. Read more here

Add some codes :

def create(conn, %{"user" => user_params}) do
IO.puts "========= My debug here"
IO.puts user_params["email"]
IO.puts "user email is #{user_params["email"]}"
...
end

After click REGISTER button, the log will be printed.

Logs via mix phx.server

2 - IO.inspect

Print all data structures, including lists, structs, tuples, and maps. Returns all variable names and their values. We can add inspect to print user_params with map type . Read more here

Add code for print user_params :

def create(conn, %{"user" => user_params}) do
IO.puts "========= My debug here"
IO.puts user_params["email"]
IO.puts "user email is #{user_params["email"]}"
IO.inspect user_params
...
end

Using IO.inspect, we can print user_params with the map type, if we use IO.puts to handle this, the app will throw an error.

We can replace IO.puts with IO.inspect and the code still run as expected.

Logs via mix phx.server

3 - dbg

dbg is similar to IO.inspect/2, but it also prints the code and location. We can use dbg with interactive elixir.

3.1 - dbg without argument

def create(conn, %{"user" => user_params}) do
dbg()
...
end

the output will be like this, all will be printed from current context. If we look at this code, it will print conn and user_params with the current elixir location ([lib/.../xxx.ex:15: xxx.create/2]).

[info] POST /users/register
[debug] Processing with TulisWeb.UserRegistrationController.create/2
Parameters: %{"_csrf_token" => "Ax8lCC0aARAyKwB6bkokBEEcNgkFMgcpiijcdwBzsNJC_yScvFboSm4M", "user" => %{"email" => "myemail@phoenix.com", "password" => "[FILTERED]"}}
Pipelines: [:browser, :redirect_if_user_is_authenticated]
[lib/tulis_web/controllers/user_registration_controller.ex:15: TulisWeb.UserRegistrationController.create/2]
binding() #=> [
conn: %Plug.Conn{
adapter: {Plug.Cowboy.Conn, :...},
assigns: %{current_user: nil},
body_params: %{},
cookies: %{},
......
},
user_params: %{"email" => "myemail@phoenix.com", "password" => "wowpassword"}
]

3.2 - dbg with argument

If we need to specify a data to print, we can pass an argument to dbg().

def create(conn, %{"user" => user_params}) do
dbg(user_params)
...
end

The output will like this,

Logs via mix phx.server

3.3 - dbg with interactive elixir (iex)

With interactive elixir, we can pry our dbg(). But, we need to run Phoenix server using this command.

iex -S mix phx.server

Click the Register button again and the terminal will look like this.

Logs via iex -S mix phx.server

We can now interact with and execute our code after pressing Y . For example :

Logs via iex -S mix phx.server

This is useful, instead of using IO.puts and IO.inspect we can use this for better debugging if there are any special cases.

Recaps — TL:DR

We can debug elixir code in several ways.

  • IO.puts
  • IO.inspect
  • dbg with argument
  • dbg without argument
  • dbg with interactive elixir

You can read this official blog for more references. Thanks for reading 📚

--

--

ervinismu
pengenpaham

full time writer, part time software engineer, long life learner