Я полагаюсь на то, что Ecto вернет ошибку, когда вставка не соответствует ограничению уровня базы данных.

Можно ли запускать другой код в зависимости от типа ошибки, возвращаемой Ecto?

case Repo.insert(changeset) do
        {:ok, _} ->
            IO.puts("inserted")
        {:error, message} when is_certain_ecto_error ->
            IO.puts("database constraint error")
        {:error, message}  ->
            IO.puts("everything else error")
end
5
henry.oswald 14 Июл 2017 в 19:22
1
Ecto вернет кортеж {:error, changeset} при неудачной вставке. Вам нужно будет посмотреть на ошибки и решить, что делать.
 – 
Justin Wood
14 Июл 2017 в 19:27
1
Итак, полная проверка струн? Есть ли хороший способ проверки типа Ecto.ConstraintError
 – 
henry.oswald
14 Июл 2017 в 19:32

2 ответа

Как сказал Джастин, вы получите {:error, changeset}, в наборе изменений будет список ключевых слов errors, где вы можете найти соответствие по шаблону.

case Repo.insert(changeset) do
    {:ok, _} -> 
        IO.puts("inserted")
    {:error, %{ errors: errors }} ->                  
        Enum.map(errors, &handle_error(&1))
end

defp handle_error({:user_name, {message, _}}) do
   "User name error:" <> message
end
defp handle_error({_some_key, _error_tuple}), do: "some error"
3
webdeb 15 Июл 2017 в 01:31

Вы всегда можете переписать свой код, чтобы использовать блок try / rescue или простое сопоставление по шаблону с Ecto.ConstraintError, поскольку это не что иное, как структура.

Вы можете использовать простое сопоставление шаблонов с этой структурой или даже с картой.

case error do
   %Ecto.ConstraintError{} -> do_something()
   _ -> do_something_else()
end

На мой взгляд, лучшее решение - создать функцию, которая обрабатывает все ошибки, которые вы можете получить, и использовать сопоставление с образцом в сигнатуре функции, например.

def handle_error_from_ecto(%Ecto.ConstraintError{} = error) do
  # do something here
end
0
PatNowak 14 Июл 2017 в 20:42