Så vitt jag vet finns det ingen inbyggd mekanism för att hantera anpassade PostgreSQL:s fel. Du kan dock göra det på förvarsnivå.
För att göra det måste du skapa fel i PostgreSQL med ERRCODE
gillar:
RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';
och hantera dem sedan 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
Notera {:error, %{changeset | valid?: false}}
svar. Det betyder att det vid den tidpunkten inte kommer att finnas något användbart meddelande att visa.
PS du kan förmodligen skriva några makron för att åsidosätta Ectos funktioner och dölja implementeringen där (istället för den föreslagna lösningen) men jag tror att det skulle vara mycket svårare att underhålla.