Problem to use Ecto errors under a pattern

Hello, I always use phoenix ecto and I have had no problem with it, but now I have to use elixir project, please see this outputs:

Error:

{:error,
 #Ecto.Changeset<
   action: :update,
   changes: %{
     email: "email@gmail89.1com",
     name: "username",
     password: "hell",
     username: "username-name"
   },
   errors: [
     password: {"pass",
      [count: 7, validation: :length, kind: :min]}
   ],
   data: #AuthService.Users.UserSchema<>,
   valid?: false
 >}

and work output

#Ecto.Changeset<
  action: nil,
  changes: %{username: "username"},
  errors: [],
  data: #AuthService.Users.UserSchema<>,
  valid?: true
>

now my code:

  def edit_user(id, attrs) do
    with {:ok, user_id} <- Ecto.UUID.cast(id), {:ok, user} <- find_user_with_user_id(user_id) do
      UserSchema.changeset(user, attrs)
      |> Repo.update
    else
      {:error, msg} ->
        {:error, msg}
      _ ->
        {:error, "User dosent exist"}
    end
  end

always the code print {:error, "User dosent exist"}, but I have written {:error, msg}, and it does not consider. even I used this code on my with flow:

{:ok, _info} <- UserSchema.changeset(user, attrs)

why is it different and I can’t handle it on some pattern, I used some code like this before

  def edit_user(id, new_params) do
    get_user_by_id(id)
    |> UserSchema.changeset(new_params)
    |> Repo.update
  end

and I could check it’s output by case and …

case Repo.insert(changeset) do
  {:ok, user}  -> 	{:ok, user}
  {:error, changeset} ->  {:error, changeset}
end

I can separate my functions and handle it, but I want to know is there a better way or not ?

Ecto.UUID.cast/1 returns :error in its error case, that doesn’t match {:error, msg} perhaps your ID can’t be cast?

thank you,

I changed my code like this:

  def update_user(user, attrs) do
    UserSchema.changeset(user, attrs)
    |> Repo.update
  end

  def edit_user(id, attrs) do

    IO.inspect update_user(find_user_with_user_id(id), attrs)
    with {:ok, user_id} <- Ecto.UUID.cast(id), {:ok, user} <- find_user_with_user_id(user_id), {:ok, info} <- update_user(user, attrs) do
      {:ok, info}
    else
      n ->
        IO.inspect n
      {:error, msg} ->
        {:error, msg}
      _ ->
        {:error, "User dosent exist"}
    end
  end

when I write this:

IO.inspect update_user(find_user_with_user_id(id), attrs)

I have this:

{:ok,
 %AuthService.Users.UserSchema{
   __meta__: #Ecto.Schema.Metadata<:loaded, "user">,
   email: "email@gmail.s1com",
   id: "8e5025c6-54e8-43c3-95c2-5dabfcecf08d",
   .....
 }}

but in with it is printed:

%AuthService.Users.UserSchema{
  __meta__: #Ecto.Schema.Metadata<:loaded, "user">,
  email: "email@gmail.s1com",
  id: "8e5025c6-54e8-43c3-95c2-5dabfcecf08d",
  ......
}

that doesn’t match , I don’t know why?

How is find_user_by_user_id defined?

my UUID.cast

IO.inspect Ecto.UUID.cast(id)
{:ok, "8e5025c6-54e8-43c3-95c2-5dabfcecf08d"}
  def find_user_with_user_id(id) do
    Repo.get(UserSchema, id)
  end

I used it,

  def find_user_with_user_id(id) do
    Repo.get_by(UserSchema, id: id)
  end

but it is not different

  defp deps do
    [
      {:ecto, "3.0.7"}, #1
      {:ecto_sql, "~> 3.0"}, #2
      {:postgrex, ">= 0.0.0"}, #3
    ]
  end

Repo.get and Repo.get_by both return the struct, not a tuple according to its documentation, I have no clue why you pre-with-inspect does show an :ok-tuple.


edit:

Oh, I see… you pre-with-inspect does also call into update_user, which in with does not happen.

Hmm, I don’t understand how I can fix it, unfortunately.
I think it means I should create a function that can create tuple like this ?

case find_user_with_user_id(id) do
nil -> {:error, ....}
user -> {:ok , user}
end

I edited my code:

  def edit_user(id, attrs) do
    with {:ok, user_id} <- Ecto.UUID.cast(id), %AuthService.Users.UserSchema{} = user <- find_user_with_user_id(user_id), {:ok, info} <- update_user(user, attrs) do
      {:ok, info}
    else
      {:error, msg} -> {:error, msg}
      _ ->
        {:error, "User dosent exist"}
    end
  end

but I think something is wrong here !! :thinking: