gpt4 book ai didi

postgresql - 如何引发自定义 Postgresql 错误并在 Ecto 中处理它

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

我在 Postgresql 中创建了一个自定义函数,它在插入或更新之前检查数据并在出现问题时引发错误。

CREATE FUNCTION custom_check() RETURNS TRIGGER AS $$
BEGIN
IF <SOME CONDITION> THEN
RAISE EXCEPTION 'CUSTOM ERROR';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
""")

当我在 Postgresql 中使用约束时,我可以处理 Ecto.Changeset.check_constraint 引发的错误。

但我没有找到一种方法来处理我提出的这个错误,将它反射(reflect)在变更集中而不是获取异常并可能在我的代码中捕获它。

我应该为 Ecto.Changeset.check_constraint 引发不同的错误来处理它,还是做其他不同的事情?

最佳答案

据我所知,没有用于处理自定义 PostgreSQL 错误的内置机制。但是,您可以在存储库级别执行此操作。

为此,您必须使用 ERRCODE 在 PostgreSQL 中引发错误,例如:

RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';

然后在应用程序中处理它们:

defmodule Core.Repo do
use Ecto.Repo, otp_app: :core

defoverridable insert: 2

def insert(changeset, opts) do
super(changeset, opts)
rescue
exception in Postgrex.Error ->
handle_postgrex_exception(exception, __STACKTRACE__, changeset)
end

# ... other functions

defp handle_postgrex_exception(exception, stacktrace, changeset \\ nil)

defp handle_postgrex_exception(%{postgres: %{code: :integrity_constraint_violation}}, _, nil) do
{:error, :integrity_constraint_violation}
end

defp handle_postgrex_exception(
%{postgres: %{code: :integrity_constraint_violation}},
_,
changeset
) do
{:error, %{changeset | valid?: false}}
end

defp handle_postgrex_exception(exception, stacktrace, _) do
reraise(exception, stacktrace)
end
end

注意 {:error, %{changeset | valid?: false}} 响应。这意味着此时不会显示任何有用的消息。

PS 你可能会写一些宏来覆盖 Ecto 的函数并在那里隐藏实现(而不是建议的解决方案)但我相信它会更难维护。

关于postgresql - 如何引发自定义 Postgresql 错误并在 Ecto 中处理它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53122256/

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