Phoenix-ArgumentError at POST

I’m new and just learning Phoenix. It seems to me there’s a lot of stuff happening"behind the curtain", and I have no idea how I’m supposed to debug it.

My app is crashing. There are two lines in the middle of the stack trace that reference my code. They both point at the same line, the defmodule in one of my controllers. After the line number, the first has my-controller-name.action/2. The second my-controller-name.phoenix_controller_pipeline/2.

Where would I even start to debug this?

TIA

Checking the source. Checking your tests. Adding in some pry's or inspect's. Posting the complete stacktrace at the forums here (^.^) or even a minimal reproduceable project. Etc… :slight_smile:

Hard to give some precise debugging tips until we see what the stacktrace is, and maybe the code. :slight_smile:

1 Like

I’m working thru “Programming Elixir” 2016. It’s supposed to gracefully handle the case when the user tries to create a duplicate user. Instead it crashes.

Here’s the stack trace:

[error] #PID<0.379.0> running Rumbl.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /users
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        :erlang.apply("new.html", :private, [])
        (phoenix) lib/phoenix/controller.ex:136: Phoenix.Controller.action_name/1
        (phoenix) lib/phoenix/controller.ex:488: Phoenix.Controller.render/2
        (rumbl) web/controllers/user_controller.ex:1: Rumbl.UserController.action/2
        (rumbl) web/controllers/user_controller.ex:1: Rumbl.UserController.phoenix_controller_pipeline/2
        (rumbl) lib/rumbl/endpoint.ex:1: Rumbl.Endpoint.instrument/4
        (rumbl) lib/phoenix/router.ex:261: Rumbl.Router.dispatch/2
        (rumbl) web/router.ex:1: Rumbl.Router.do_call/2
        (rumbl) lib/rumbl/endpoint.ex:1: Rumbl.Endpoint.phoenix_pipeline/1
        (rumbl) lib/plug/debugger.ex:123: Rumbl.Endpoint."call (overridable 3)"/2
        (rumbl) lib/rumbl/endpoint.ex:1: Rumbl.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) /home/justin/Documents/workspaces/phoenix/rumbl/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

Here’s the source file referenced in the stack trace.

defmodule Rumbl.UserController do
    use Rumbl.Web, :controller

    plug :authenticate_user when action in [:index, :show]


    alias Rumbl.User

    def new(conn, _params) do
        changeset = User.changeset(%User{})
        render conn, "new.html", changeset: changeset
    end
    
    def index(conn, _params) do
        users = Repo.all(Rumbl.User)
        render conn, "index.html", users: users
    end

    def show(conn, %{"id" => id}) do
        user = Repo.get(Rumbl.User, id)
        render conn, "show.html", user: user
    end

    def create(conn, %{"user" => user_params}) do
        changeset = User.registration_changeset(%User{}, user_params)
        case Repo.insert(changeset) do
            {:ok, user} ->
                conn
                |> Rumbl.Auth.login(user)
                |> put_flash(:info, "#{user.name} created!")
                |> redirect(to: user_path(conn, :index))   
            {:error, changeset} ->
                render("new.html", changeset: changeset)                 
        end
    end

end

My entire project is available here:
https://github.com/Justin-E-Taylor/Rumbl-unique_constraint

you need to pass conn to render function

{:error, changeset} ->
                render(conn, "new.html", changeset: changeset)

What in the error points to that being the problem?

“Give a man a fish, feed him for a day. Teach a man to fish and feed him for a lifetime.”

Thanks

@Justin

This part:

:erlang.apply("new.html", :private, [])

Means it tried to do this:

"new.html".private

And private is a thing on conn that is used by phoenix a lot, and checking your code where render was called you have:

render("new.html", changeset: changeset)    

Which takes conn in the first position, but instead you passed in "new.html" in the first position, so it was trying to call .private on that instead of the conn map. :slight_smile:

Phoenix should probably add a matcher on %Plug.Conn{} on those calls, the error message would be more obvious. PR it? :slight_smile:

1 Like

Thank you