Unraveling This Ball of Suck

What we've just run into is an OTP process not being able to talk to another OTP process. Let this error seer into your eyes, because this is not the last time you'll see it:

** (EXIT) no process

I believe I have spent days on no process errors, and only now have I begun to understand how to troubleshoot them. Let's walk through this together.

The first thing to do is to sit back and visualize the application you've created. We know that at the top level we have an application called Physics and that it requires other applications - we set this up in our mix.exs file:

applications: [:logger, :timex, :postgrex, :ecto]

When our application starts, it will, in turn, startup Logger, Timex, Postgrex and Ecto. This will start our Repo and off we go. But that's not what's happening here.

Looking at the exact error, we see that :erlang is trying to send a message to Physics.Repo.Pool:

 ** (EXIT) no process
    :erlang.send(Physics.Repo.Pool, {:"$gen_cast", {:cancel_waiting, #Reference<>}}, [:noconnect]) # example 1
    (stdlib) gen_server.erl:416: :gen_server.do_send/2
    (stdlib) gen_server.erl:232: :gen_server.do_cast/2
    src/poolboy.erl:58: :poolboy.checkout/3
    lib/db_connection/poolboy.ex:36: DBConnection.Poolboy.checkout/2
    lib/db_connection.ex:811: DBConnection.checkout/2
    lib/db_connection.ex:717: DBConnection.run/3
    lib/db_connection.ex:421: DBConnection.query/4

Reading this stack trace from bottom to top, we can reason that:

  • DBConnection is trying to execute a query. We've made it this far, which is good!
  • Upon trying to checkout something, a library called Poolboy is trying use a GenServer without success.
  • The error is not coming from Ecto or Postgrex, the driver. This is critical - it's coming from Erlang which stops everything saying "I don't have the process you want".

The thing we need to figure out is this: what process is Erlang trying to find?