diff --git a/integration_test/myxql/storage_test.exs b/integration_test/myxql/storage_test.exs index 8df18235..8ba35487 100644 --- a/integration_test/myxql/storage_test.exs +++ b/integration_test/myxql/storage_test.exs @@ -121,6 +121,20 @@ defmodule Ecto.Integration.StorageTest do drop_database() end + test "structure load will fail on SQL errors" do + create_database() + File.mkdir_p!(tmp_path()) + error_path = Path.join(tmp_path(), "error.sql") + File.write!(error_path, "SELECT 1; SELECKT 1; SELECT 2;") + + {:error, message} = + Ecto.Adapters.MyXQL.structure_load(tmp_path(), [dump_path: error_path] ++ params()) + + assert message =~ ~r/ERROR.*SELECKT/ + after + drop_database() + end + test "storage status is up when database is created" do create_database() assert :up == Ecto.Adapters.MyXQL.storage_status(params()) diff --git a/lib/ecto/adapters/myxql.ex b/lib/ecto/adapters/myxql.ex index c6337f1b..6c706dfe 100644 --- a/lib/ecto/adapters/myxql.ex +++ b/lib/ecto/adapters/myxql.ex @@ -588,12 +588,16 @@ defmodule Ecto.Adapters.MyXQL do args: args ] + # Trap exits in case mysql dies in the middle of execution so that we can surface the error + old_trap_exit = Process.flag(:trap_exit, true) port = Port.open({:spawn_executable, abs_cmd}, port_opts) Port.command(port, contents) # Use this as a signal to close the port since we cannot # send an exit command to mysql in batch mode Port.command(port, ";SELECT '__ECTO_EOF__';\n") - collect_output(port, "") + result = collect_output(port, "") + Process.flag(:trap_exit, old_trap_exit) + result end defp args_env(opts, opt_args) do @@ -653,6 +657,9 @@ defmodule Ecto.Adapters.MyXQL do collect_output(port, acc) end + {:EXIT, ^port, _reason} -> + {acc, 1} + {^port, {:exit_status, status}} -> {acc, status} end