Så vidt jeg ved, er der ingen indbygget mekanisme til at håndtere brugerdefinerede PostgreSQL's fejl. Du kan dog gøre det på lagerniveau.
For at gøre det skal du rejse fejl i PostgreSQL ved hjælp af ERRCODE
som:
RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';
og derefter håndtere dem i applikationen:
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
Bemærk {:error, %{changeset | valid?: false}}
respons. Det betyder, at der på det tidspunkt ikke vil være nogen brugbar besked at vise.
PS du kunne sikkert skrive nogle makroer for at tilsidesætte Ecto's funktioner og skjule implementeringen der (i stedet for den foreslåede løsning), men jeg tror, det ville være meget sværere at vedligeholde.