maz
Elixir Function Succeeding but not Returning Value
Hi all, I’m not clear why this function is not returning a value:
def confirm_email!(user = %User{email_confirmed: false}) do
confirm = User.changeset_confirm_email(user, true)
case Repo.update(confirm) do
# Updated with success
{:ok, updated_user} ->
Logger.debug("update success")
{:ok, updated_user}
{:error, _, reason, _} ->
Logger.debug("update error")
Logger.error(reason)
{:error, reason}
end
Logger.debug("end of confirm_email")
end
I see in the log:
[debug] QUERY OK db=7.2ms queue=5.3ms idle=633.5ms
UPDATE "users" SET "email_confirmation_token" = $1, "email_confirmed" = $2, "updated_at" = $3 WHERE "id" = $4 [nil, true, ~U[2020-08-19 02:18:18Z], 1]
[debug] update success
[debug] end of confirm_email
[info] Sent 204 in 85ms
The side-effect is that the page is not routing from the caller:
def confirm_email(conn, %{"token" => token}) do
Logger.debug("confirm_email token: #{token}")
case Accounts.confirm_email!(token) do
{:ok, updated_user} ->
Logger.debug("updated_user: #{updated_user}")
conn
|> Guardian.Plug.sign_in(updated_user)
|> put_flash(:info, gettext("Welcome %{user_name}!", user_name: updated_user.name))
|> redirect(to: Routes.page_path(conn, :index))
{:error, reason} ->
Logger.debug("error reason: #{reason}")
json(put_status(conn, 404), %{error: "invalid_token"})
end
end
It’s just not clear to me why it doesn’t appear to be returning the tuple I expect.
Michael
Most Liked
cmkarlsson
You are returning the result of the last Logger.debug expression which is :ok
If you really wanted the “end of confirm_email” logging you need to return the result after.
def confirm_email!(user = %User{email_confirmed: false}) do
confirm = User.changeset_confirm_email(user, true)
result = case Repo.update(confirm) do
# Updated with success
{:ok, updated_user} ->
Logger.debug("update success")
{:ok, updated_user}
{:error, _, reason, _} ->
Logger.debug("update error")
Logger.error(reason)
{:error, reason}
end
Logger.debug("end of confirm_email")
result
end
maz
I deleted my response by mistake.
You were right, the root problem was the router. I was calling
get("/confirm_email/:token", UserController, :confirm_email) # for json api
and not:
get("/confirm_email/:token", SignupController, :confirm_email)
SignupController:
def confirm_email(conn, %{"token" => token}) do
Logger.debug("confirm_email token: #{token}")
case Accounts.confirm_email!(token) do
{:ok, updated_user} ->
conn
|> Guardian.Plug.sign_in(updated_user)
|> put_flash(:info, gettext("Welcome %{user_name}!", user_name: updated_user.name))
|> redirect(to: Routes.page_path(conn, :index))
{:error, reason} ->
Logger.debug("error reason: #{reason}")
json(put_status(conn, 404), %{error: "invalid_token"})
end
end
Works fine. Thanks for the help. Guilty of programming while tired.
Leaving this here so others might benefit.
mindok
The last statement in your function is Logger.debug call, so it’s return will be your return value







