Sejauh yang saya tahu, tidak ada mekanisme bawaan untuk menangani kesalahan PostgreSQL khusus. Namun, Anda dapat melakukannya di tingkat repositori.
Untuk melakukan itu, Anda harus memunculkan kesalahan di PostgreSQL menggunakan ERRCODE
seperti:
RAISE '[message for logs]' USING ERRCODE = 'integrity_constraint_violation';
lalu tangani di aplikasi:
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
Perhatikan {:error, %{changeset | valid?: false}}
tanggapan. Artinya, pada saat itu, tidak akan ada pesan yang berguna untuk ditampilkan.
PS Anda mungkin bisa menulis beberapa makro untuk menimpa fungsi Ecto dan menyembunyikan implementasinya di sana (bukan solusi yang diusulkan) tapi saya yakin akan jauh lebih sulit untuk mempertahankannya.