id}) do with {:ok, user} put_status(200) |> render("show.json", %{us-6ren">
gpt4 book ai didi

postgresql - Elixir UUID。 UUID不匹配时如何处理500错误

转载 作者:行者123 更新时间:2023-11-29 11:48:59 27 4
gpt4 key购买 nike

def show(conn, %{"id" => id}) do
with {:ok, user} <- UserAction.get_user(id)
|> put_status(200)
|> render("show.json", %{user: user})
else
{:error, :not_found} -> {:error, :not_found, %User{id: id}}
end
end

当 id 无效时,Ecto 引发:

Ecto.Query.CastError - cannot be dumped to type :binary_id in query. 

我的 get_user 函数:

query = from(u in User, where u.id == ^id)

case Repo.all(query) do
[%User{} = user] -> {:ok, user}
_ -> {:error, :not_found}
end

是否有任何方便的方法来处理此错误以防止出现 500 次响应?

最佳答案

这是 UUIDBinary 和其他 的已知问题需要符合特定标准的类型(这是一个功能,而不是错误™️)。就像 @TheAnh 提到的,你可以使用 Ecto.UUID.dump/1 来检查 id 是否有效,但我更喜欢直接拯救它:

def get_user(id) do
Repo.get(User, id)
rescue
Ecto.Query.CastError -> nil
end

覆盖Repo

上面的示例可能会变得乏味,因为您必须在调用 get 的所有地方rescue。所以我覆盖了 MyApp.Repo 中的 get/3 函数:

# lib/my_app/repo.ex
defoverridable [get: 2, get: 3]
def get(query, id, opts \\ []) do
super(query, id, opts)
rescue
Ecto.Query.CastError -> nil
end

对元组格式使用fetch

您应该使用 fetch_* 方法名称而不是 get_*tuple 格式返回值(以避免与默认 混淆 repo 方法):

# lib/my_app/repo.ex
def fetch(query, id, opts \\ []) do
case get(query, id, opts) do
nil -> {:error, :not_found}
schema -> {:ok, schema}
end
end

然后在你的主函数中这样调用它:

def fetch_user(id) do
Repo.fetch(User, id)
end

关于postgresql - Elixir UUID。 UUID不匹配时如何处理500错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53802091/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com