Soweit ich weiß, gibt es keinen integrierten Mechanismus zur Behandlung von benutzerdefinierten PostgreSQL-Fehlern. Sie können dies jedoch auf Repository-Ebene tun.
Dazu müssen Sie Fehler in PostgreSQL mit ERRCODE
auslösen wie:
RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';
und handhabe sie dann in der Anwendung:
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
Beachten Sie den {:error, %{changeset | valid?: false}}
Antwort. Das bedeutet, dass an diesem Punkt keine nützliche Nachricht angezeigt werden kann.
PS Sie könnten wahrscheinlich einige Makros schreiben, um die Funktionen von Ecto zu überschreiben und die Implementierung dort zu verstecken (anstelle der vorgeschlagenen Lösung), aber ich glaube, es wäre viel schwieriger zu warten.