Starting Mongo inside a mix Task

I need to run some commands on a Mongo database from within a custom mix task. I’m using the mongodb driver.

The task module looks like this:

defmodule Mix.Tasks.Mongo.Stuff do
  use Mix.Task

  @shortdoc "Does stuff to mongo..."
  def run(_) do
    {:ok, _pid} = Mongo.start_link(Application.get_env(:db, DocDb))
    Mongo.find_one(:docdb, "the_collection", %{id: 456})
  end
end

and the relevant bit of the config looks like this:

config :db, DocDb,
  url: "mongodb://localhost:27017/docdb_dev",
  name: :docdb

This seems to get Mongo started (?) but it generates a spooky error:

mix mongo.stuff
Compiling 1 file (.ex)
** (EXIT from #PID<0.92.0>) an exception was raised:
    ** (ArgumentError) argument error
        :erlang.!(Mongo.Events, {:notify, %Mongo.Events.TopologyOpeningEvent{topology_pid: #PID<0.305.0>}})
        (stdlib) gen_event.erl:269: :gen_event.send/2
        lib/mongo/topology.ex:70: Mongo.Topology.init/1
        (stdlib) gen_server.erl:374: :gen_server.init_it/2
        (stdlib) gen_server.erl:342: :gen_server.init_it/6
        (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

I’m not even sure what I’m looking at. Can someone help set me straight? Thanks!

mix tasks don’t start your or any other applications. When you need some, you need to start them manually using Application.ensure_all_started/1.

3 Likes