Stuck on rendering ecto errors

I’m creating an api that inserts new user. Rendering the error from Ecto Changeset is what I want to do using JSON. It doesn’t seem to work. For example: username already taken or email already taken.

Below is the create function

 def create(conn, %{"user" => user_params}) do
    case Accounts.create_user(user_params) do
      {:ok, token, _claims} -> 
        Accounts.create_user(user_params)
        conn
        |> render("jwt.json", jwt: token)
    
      {:error, changeset} -> 
        IO.inspect(changeset.errors)
        conn
        |> put_status(:unauthorized)
        |> put_view(FakeWeb.ErrorView)
        |> render("error.json", changeset: changeset)
    end                                             
  end  

Below is the error render

def translate_errors(changeset) do
    Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
  end

  def render("error.json", %{changeset: changeset}) do
    # When encoded, the changeset returns its errors
    # as a JSON object. So we just pass it forward.
    %{errors: translate_errors(changeset)}
  end

I get a 401 response but want something also like

errors: {email: has already been taken} 

Ecto changeset struct is below:

#Ecto.Changeset<
  action: :insert,
  changes: %{
    confirmed: false,
    email: "H@gmail.com",
    is_active: false,
    is_staff: false,
    password: "fakepass",
    password_hash: "$2b$12$uKZUqpqUW2IJ48japUNoqeWIIGsNhDA97N/6VA.5ZF6f8jRtjOpm6",
    username: "Charle"
  },
  errors: [
    email: {"has already been taken",
     [constraint: :unique, constraint_name: "users_email_index"]}
  ],
  data: #Fake.Accounts.User<>,
  valid?: false
>

401 means Unauthorized. Seems like some middleware has interrupted request and create function wasn’t invoked.

I basically want to get the changeset error and turn it into a consumable api

errors: {email: has already been taken} 

I only get the 401 response. No serialized data.

So I found out what’s wrong. The output is correct. However, react native isn’t really accepting response error.


Request failed with status code 401
at node_modules/axios/lib/core/createError.js:16:14 in createError
at node_modules/axios/lib/core/settle.js:17:11 in settle
- ... 9 more stack frames from framework internals

I can’t intercept the error body from the back.