From 6c41f69723dad0861f3a73216374b6fddab44467 Mon Sep 17 00:00:00 2001 From: Bent Witthold Date: Wed, 18 Feb 2026 10:47:37 +0100 Subject: [PATCH] Creating user via API give correct responses if the user already exists or the mail address is malformed. --- .../controllers/user_controller.ex | 42 ++++++++++++++++--- .../controllers/user_json.ex | 21 ++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/lib/beet_round_server_web/controllers/user_controller.ex b/lib/beet_round_server_web/controllers/user_controller.ex index 9af1020..4c8b586 100644 --- a/lib/beet_round_server_web/controllers/user_controller.ex +++ b/lib/beet_round_server_web/controllers/user_controller.ex @@ -12,11 +12,23 @@ defmodule BeetRoundServerWeb.UserController do end def create(conn, %{"user" => user_params}) do - with {:ok, %User{} = user} <- Accounts.register_user(user_params) do - conn - |> put_status(:created) - |> put_resp_header("location", ~p"/api/users/#{user}") - |> render(:show, user: user) + case Accounts.register_user(user_params) do + {:ok, %User{} = user} -> + send_created_response(conn, user) + + {:error, changeset} -> + with %User{} = user <- Accounts.get_user_by_email(user_params["email"]) do + send_already_reported_response(conn, user) + else + _ -> + send_not_acceptable(conn, changeset) + end + + _ -> + conn + |> put_status(:bad_request) + |> put_resp_header("location", ~p"/api/users") + |> render(:show, changeset: "Bad request") end end @@ -40,4 +52,24 @@ defmodule BeetRoundServerWeb.UserController do # send_resp(conn, :no_content, "") # end # end + + defp send_created_response(conn, %User{} = user) do + conn + |> put_status(:created) + |> put_resp_header("location", ~p"/api/users/#{user}") + |> render(:show, %{user: user}) + end + + defp send_already_reported_response(conn, %User{} = user) do + conn + |> put_status(:already_reported) + |> render(:show, %{user: user}) + end + + defp send_not_acceptable(conn, changeset) do + conn + |> put_status(:not_acceptable) + |> put_resp_header("location", ~p"/api/users") + |> render(:show, changeset: changeset) + end end diff --git a/lib/beet_round_server_web/controllers/user_json.ex b/lib/beet_round_server_web/controllers/user_json.ex index 83f754c..bc10b20 100644 --- a/lib/beet_round_server_web/controllers/user_json.ex +++ b/lib/beet_round_server_web/controllers/user_json.ex @@ -15,10 +15,31 @@ defmodule BeetRoundServerWeb.UserJSON do %{data: data(user)} end + def show(%{changeset: changeset}) do + # When encoded, the changeset returns its errors + # as a JSON object. So we just pass it forward. + %{errors: Ecto.Changeset.traverse_errors(changeset, &translate_error/1)} + end + defp data(%User{} = user) do %{ id: user.id, email: user.email } end + + defp translate_error({msg, opts}) do + # You can make use of gettext to translate error messages by + # uncommenting and adjusting the following code: + + # if count = opts[:count] do + # Gettext.dngettext(BeetRoundServerWeb.Gettext, "errors", msg, msg, count, opts) + # else + # Gettext.dgettext(BeetRoundServerWeb.Gettext, "errors", msg, opts) + # end + + Enum.reduce(opts, msg, fn {key, value}, acc -> + String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end) + end) + end end