简体   繁体   中英

Elixir getting error from controller: Expected action/2 to return a Plug.Conn

I have this small controller to handle user registration

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

    IO.inspect(user_params)

    errors = []

    cond do
      user_params["name"] === nil              -> errors = ["Name cannot be empty" | errors ]
      String.length(user_params["name"]) >= 50 -> errors = ["Name cannot be longer than 50 characters" | errors ]
      String.length(user_params["name"]) <= 3  -> errors = ["Name cannot be shorter than 3 characters" | errors ]
    end
    cond do
      user_params["email"] === nil              -> errors = ["Email cannot be empty" | errors ]
      String.length(user_params["email"]) >= 50 -> errors = ["Email cannot be longer than 50 characters" | errors ]
      String.length(user_params["email"]) <= 5  -> errors = ["Email cannot be shorter than 3 characters" | errors ]
    end
    cond do
      user_params["username"] === nil              -> errors = ["Username cannot be empty" | errors ]
      String.length(user_params["username"]) >= 30 -> errors = ["Username cannot be longer than 30 characters" | errors ] 
      String.length(user_params["username"]) <= 3  -> errors =  ["Username cannot be shorter than 3 characters" | errors ]
    end
    cond do
      user_params["password"]  === nil             ->         errors = ["Password cannot be empty" | errors ]
      user_params["passwordC"] === nil             ->         errors = ["Password Confirmation cannot be empty" | errors ]
      String.length(user_params["password"]) >= 30 ->         errors = ["Password cannot be longer than 30 characters" | errors ]
      String.length(user_params["password"]) <= 3  ->         errors = ["Password cannot be shorter than 3 characters" | errors ]
      user_params["password"] !== user_params["passwordC"] -> errors = ["Passwords do not match" | errors ]
    end

    cond do
      (length errors) >= 1 -> conn |> json %{success: false, errors: errors}
      (length errors) == 0 -> conn |> json %{success: true} 
    end
end

I get the json response, but I keep raising this exception:

Request: POST /auth/register
** (exit) an exception was raised:
    ** (RuntimeError) expected action/2 to return a Plug.Conn, all plugs must receive a connection (conn) and return a connection
        (bdo_pug) web/controllers/user_controller.ex:1: BdoPug.UserController.phoenix_controller_pipeline/2
        (bdo_pug) lib/phoenix/router.ex:261: BdoPug.Router.dispatch/2
        (bdo_pug) web/router.ex:1: BdoPug.Router.do_call/2
        (bdo_pug) lib/bdo_pug/endpoint.ex:1: BdoPug.Endpoint.phoenix_pipeline/1
        (bdo_pug) lib/plug/debugger.ex:93: BdoPug.Endpoint."call (overridable 3)"/2
        (bdo_pug) lib/phoenix/endpoint/render_errors.ex:34: BdoPug.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

I've googled it and it keeps telling me I need to return the conn which I believe I am. Any information would be great thanks.

The entire controller for extra detail

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

  alias BdoPug.User

  plug :scrub_params, "user" when action in [:create, :update]

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

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

    errors = []

    cond do
      user_params["name"] === nil              -> errors = ["Name cannot be empty" | errors ]
      String.length(user_params["name"]) >= 50 -> errors = ["Name cannot be longer than 50 characters" | errors ]
      String.length(user_params["name"]) <= 3  -> errors = ["Name cannot be shorter than 3 characters" | errors ]
    end
    cond do
      user_params["email"] === nil              -> errors = ["Email cannot be empty" | errors ]
      String.length(user_params["email"]) >= 50 -> errors = ["Email cannot be longer than 50 characters" | errors ]
      String.length(user_params["email"]) <= 5  -> errors = ["Email cannot be shorter than 3 characters" | errors ]
    end
    cond do
      user_params["username"] === nil              -> errors = ["Username cannot be empty" | errors ]
      String.length(user_params["username"]) >= 30 -> errors = ["Username cannot be longer than 30 characters" | errors ] 
      String.length(user_params["username"]) <= 3  -> errors =  ["Username cannot be shorter than 3 characters" | errors ]
    end
    cond do
      user_params["password"]  === nil             ->         errors = ["Password cannot be empty" | errors ]
      user_params["passwordC"] === nil             ->         errors = ["Password Confirmation cannot be empty" | errors ]
      String.length(user_params["password"]) >= 30 ->         errors = ["Password cannot be longer than 30 characters" | errors ]
      String.length(user_params["password"]) <= 3  ->         errors = ["Password cannot be shorter than 3 characters" | errors ]
      user_params["password"] !== user_params["passwordC"] -> errors = ["Passwords do not match" | errors ]
    end

    cond do
      (length errors) >= 1 -> conn |> json %{success: false, errors: errors}
      (length errors) == 0 -> conn |> json %{success: true} 
    end

    """
    case Repo.insert(changeset) do
      {:ok, _user} ->
        conn
        |> put_flash(:info, "User created successfully.")
        |> redirect(to: user_path(conn, :index))
      {:error, changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
    """
  end

  def loginView(conn, _params) do
    render(conn, "loginView.html")
  end

  def loginPost(conn, %{"user" => user_params}) do

  end
end

It seems like you wrapped the auto-generated case statement in """ . In Elixir, """ is the start of a HEREDOC, so you've essentially created one large string at the end of your function. Elixir functions return the last value in the function body which is either a raw value or the result of a function. So instead of returning the Plug.Conn struct expected by the calling function, it's returning the string of the HEREDOC since that's the last value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM