zookzook / elixir-mongodb-driver

MongoDB driver for Elixir
Apache License 2.0
247 stars 63 forks source link

`mix mongo.migrate` Doesn't log any errors. #257

Open PsychicPlatypus opened 2 weeks ago

PsychicPlatypus commented 2 weeks ago

Description

I tried making a migration for my project, so I did:

mix mongo.gen.migration my_migration

And then in the Generated file I wrote my migration code, but I accidentally made an error in the code:

defmodule Mongo.Migrations.MyTopology.MyMigration do
  @topology :my_topology
  @index_name "foo.bar_1_baz_1"

  def up() do
    index = [key: ["foo": 1, bar: 1], name: @index_name, background: true]
    Mongo.create_indexes(@topology, "myCollection", index, timeout: :infinity) # <~ index should be [index] instead !!!
  end

  def down() do
    Mongo.drop_index(@topology, "myCollection", @index_name)
  end
end

But even though there was an error in the migration, the task just said something like:

🔒 listen_migrations locked
⚡️ my_migration succesfull
🔓 listen_migrations unlocked

When running the migration manually via the iex session I actually get the correct error:

{:error,
 %Mongo.Error{
   message: "BSON field 'createIndexes.indexes' is the wrong type 'object', expected type 'array'",
   code: 14,
   host: nil,
   fail_command: false,
   error_labels: [],
   resumable: false,
   retryable_reads: false,
   retryable_writes: false,
   not_writable_primary_or_recovering: false,
   error_info: nil
 }}

Expected Behaviour

The mix mongo.migrate task should at least log any errors that happen and stop running further migrations, because i can imagine this causing some major issues if I didn't check the migration first.

zookzook commented 2 weeks ago

As long as the function does not throw an exception, everything is fine. Maybe you need to change your migration code to crash if the expected result is not returned:

:ok = Mongo.create_indexes(...)
zookzook commented 2 weeks ago

Keep in mind a migration can also update existing documents. If the query is wrong, then the server won't return an error. In this case, you need to check if the modified_count attribute returned by the update_many function contains the expected number of updates.