Voor zover ik weet, is er geen ingebouwd mechanisme voor het afhandelen van aangepaste PostgreSQL-fouten. U kunt het echter wel op repository-niveau doen.
Om dat te doen, moet u fouten in de PostgreSQL genereren met behulp van ERRCODE
zoals:
RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';
en behandel ze vervolgens in de applicatie:
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
Let op de {:error, %{changeset | valid?: false}}
antwoord. Het betekent dat er op dat moment geen nuttig bericht zal zijn om weer te geven.
PS je zou waarschijnlijk wat macro's kunnen schrijven om de functies van Ecto te negeren en de implementatie daar te verbergen (in plaats van de voorgestelde oplossing), maar ik denk dat het veel moeilijker te onderhouden zou zijn.