Plug call results in an argument error

Hello geeks,

I just wrote my first plug, here is it:

defmodule RumblWeb.AuthController do
  import Plug.Conn
  def init(opts) do
    Keyword.fetch(opts, :repo)

  def call(conn, repo) do
    user_id = get_session(conn, :user_id)
    user = user_id && repo.get(Rumbl.User, user_id)
    assign(conn, :current_user, user)

but whenever I try to access the route that uses that plug I get the following error ** (ArgumentError) argument error :erlang.apply({:ok, Rumbl.Repo}, :get, []) (rumbl) lib/rumbl_web/controllers/auth_controller.ex:9: (rumbl) RumblWeb.Router.browser/2 (rumbl) lib/rumbl_web/router.ex:1: RumblWeb.Router.__pipe_through0__/1 (phoenix) lib/phoenix/router.ex:283: Phoenix.Router.__call__/2 (rumbl) lib/rumbl_web/endpoint.ex:1: RumblWeb.Endpoint.plug_builder_call/2 (rumbl) lib/plug/debugger.ex:122: RumblWeb.Endpoint."call (overridable 3)"/2 (rumbl) lib/rumbl_web/endpoint.ex:1: (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:42: Phoenix.Endpoint.Cowboy2Handler.init/4
any help?

Thanks in advance.

Welcome to the forum!

The result returned by init/1 is passed as second argument to call/2 . Note that init/1 may be called during compilation and as such it must not return pids, ports or values that are not specific to the runtime.

So what is passed in the opts of call/2 isn’t the repo.

From page 89 of Programming Phoenix 1.4

Note how _opts argument is ignored and the repo is accessed via the Accounts context.

You may want to have a look at

The error message is based on this:

:erlang.apply({:ok, Rumbl.Repo}, :get, [])

So what happened:

  def init(opts) do
    Keyword.fetch(opts, :repo)

Keyword.fetch/2 returns a tuple that was then passed as the opts parameter. But even

  def init(opts) do
    {:ok, repo} = Keyword.fetch(opts, :repo)

Would just return the Rumbl.Repo atom value that is simply the name of the module.


Wow, Thank you very much for this answer.