Nona
Nona

Reputation: 5472

Rescuing an Ecto.ConstraintError to keep a migration rolling?

How do you rescue an Ecto.ConstraintError (caused by a uniqueness conflict - I have a unique index on a string property called "field")

Here is the code I have that is still raising the Error and doesn't seem to rescue - the ecto.migration stops:

    try do
      Repo.insert(model_changeset, on_conflict: :nothing)
    rescue
      e -> IO.puts(inspect e)
    end

One other thing to note - sometimes model_changeset is not a changeset but a struct - should I always pass a changeset? I assume with the rescue clause it wouldn't matter - I should be able to rescue any general error according to the way I specified it.

EDIT:

Here's the relevant error message:

%Ecto.ConstraintError{constraint: "cars_field_index", message: "constraint error when attempting to insert struct:\n\n    * unique: claims_name_index\n\nIf you would like to convert this constraint into an error, please\ncall unique_constraint/3 in your changeset and define the proper\nconstraint name. The changeset has not defined any constraint.\n", type: :unique}
** (DBConnection.ConnectionError) transaction rolling back

Upvotes: 1

Views: 418

Answers (1)

MartinElvar
MartinElvar

Reputation: 5804

Add a unique constraint to your changeset unique_constraint/3 (https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3), it basically turns the database error into a changeset error.

Then you can use a case statement.

case Repo.insert(model_changeset) do 
  {:ok, schema} -> schema 
  {:error, changeset} -> IO.inspect changeset
end

Upvotes: 3

Related Questions