Error with saving to mongo db

Hello!
Like a mongodb driver for elixir I using Mongo.Ecto.

When I try to save something using using command insert:

of = %Friends.Person{age: 44}
Friends.Repo.insert(of)

I got error:

** (exit) exited in: GenServer.call(Friends.Repo.Pool, :topology, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir) lib/gen_server.ex:824: GenServer.call/3
    (mongodb) lib/mongo.ex:750: Mongo.select_servers/4
    (mongodb) lib/mongo.ex:727: Mongo.select_server/3
    (mongodb) lib/mongo.ex:501: Mongo.insert_one/4
    (mongodb_ecto) lib/mongo_ecto/connection.ex:120: Mongo.Ecto.Connection.insert/3
    (mongodb_ecto) lib/mongo_ecto.ex:630: Mongo.Ecto.insert/6
    (ecto) lib/ecto/repo/schema.ex:469: Ecto.Repo.Schema.apply/4
    (ecto) lib/ecto/repo/schema.ex:205: anonymous fn/13 in Ecto.Repo.Schema.do_insert/4

I did everything as in a guide: https://hexdocs.pm/ecto/getting-started.html

Please double check if you have started your supervision tree and your repo gets started as a part of it.

My lib/friends/aplication.ex file:

defmodule Friends.Application do
  # See https://hexdocs.pm/elixir/Application.html
  # for more information on OTP Applications
  @moduledoc false

  use Application

  def start(_type, _args) do
    # List all child processes to be supervised
    children = [
      Friends.Repo
      # {Friends.Worker, arg},
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: Friends.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Can you tell me which versions of the mongodb_ecto and mongodb packages you are using?

mongo_ecto -v 0.2.0

Are you getting any errors on startup saying that something failed? Have you tried running a mix deps.clean?

I didn’t got any error.
mix deps.clean didn’t help.

What version of the mongodb package are you using?

v3.6.3

That version doesn’t exist for the mongodb package. The latest version is 0.4.5 (unless you are using a different package). Can you just copy the relevant lines from the mix.lock file?

ohh, sorry I realy use 0.4.5 version:

"mongodb": {:hex, :mongodb, "0.4.5", "b46e7fdbbcc1f6ba7b893f5ddcc154b59858e0940794a955ab3ce8ae8bbe970b", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}], "hexpm"},
  "mongodb_ecto": {:hex, :mongodb_ecto, "0.2.0", "5eccf19f3798c0a5c39428c6d33394b55038f902bd60f7a4fb1f9ffb1f4ece97", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mongodb, "~> 0.4.2", [hex: :mongodb, repo: "hexpm", optional: false]}], "hexpm"}

What about your ecto version?

Is this code from within your app or are you running those commands through iex?

If its from the app, how are you starting the app? Is the code public?

If it is from iex, how do you start iex?

It is from iex, I start it through iex -S mix.
ecto v2.1.6

Could you please make a small repo on github with the code to reproduce this? That would help us identify the problem on our own machines and then walk you through a (hopefully) solution.

1 Like

What does your mixfiles application function look like?

Is it (close to) the following?

def application do
  [mod: {Friends.Application, []}]
end
1 Like

https://github.com/dersar00/friends

As @NobbZ suggested, you need to add your application to your application function in mix.exs (https://github.com/dersar00/friends/blob/master/mix.exs#L15-L20), otherwise it won’t be started.

Try replacing

  def application do
    [
      # NOTE: I think you should use either :extra_applications or :applications
      # see https://www.amberbit.com/blog/2017/9/22/elixir-applications-vs-extra_applications-guide/
      applications: [:method_missing, :logger, :mongodb_ecto, :ecto],
      extra_applications: [:logger]
    ]
  end

with

def application do
  [
    mod: {Friends.Application, []}, # points to the module with application
    extra_applications: [:logger]
  ]
end
1 Like

I got error:

Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Compiling 4 files (.ex)
Generated friends app
10:20:39.246 [error] Supervisor 'Elixir.Logger.Supervisor' had child 'Elixir.Logger.ErrorHandler' started with 'Elixir.Logger.Watcher':start_link({error_logger,'Elixir.Logger.ErrorHandler',{true,false,500}}) at <0.228.0> exit with reason normal in context child_terminated
10:20:39.299 [info] Application lager started on node nonode@nohost
10:20:39.304 [info] Application xmerl started on node nonode@nohost
10:20:39.307 [info] Application jsx started on node nonode@nohost
10:20:39.317 [info] Application ranch started on node nonode@nohost
10:20:39.320 [info] Application ranch_proxy_protocol started on node nonode@nohost
10:20:39.322 [info] Application recon started on node nonode@nohost
10:20:39.322 [info] Application rabbit_common started on node nonode@nohost
10:20:39.329 [info] Application amqp_client started on node nonode@nohost
10:20:39.330 [info] Application amqp started on node nonode@nohost
10:20:39.343 [info] Application decimal started on node nonode@nohost
10:20:39.345 [info] Application poolboy started on node nonode@nohost
10:20:39.350 [info] Application ecto started on node nonode@nohost
10:20:39.355 [info] Application connection started on node nonode@nohost
10:20:39.379 [info] Application db_connection started on node nonode@nohost
10:20:39.414 [info] Application mongodb started on node nonode@nohost
10:20:39.414 [info] Application mongodb_ecto started on node nonode@nohost
10:20:39.442 [error] CRASH REPORT Process <0.303.0> with 0 neighbours exited with reason: #{'__exception__' => true,'__struct__' => 'Elixir.ArgumentError',message => <<"The module Friends.Repo was given as a child to a supervisor\nbut it does not implement child_spec/1.\n\nIf you own the given module, please define a child_spec/1 function\nthat receives an argument and returns a child specification as a map.\nFor example:\n\n    def child_spec(opts) do\n      %{\n        id: __MODULE__,\n        start: {__MODULE__, :start_link, [opts]},\n        type: :worker,\n        restart: :permanent,\n  ...">>} in 'Elixir.Supervisor':init_child/1 line 635 in application_master:init/4 line 134

10:20:39.471 [info]  Application friends exited: exited in: Friends.Application.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (ArgumentError) The module Friends.Repo was given as a child to a supervisor
but it does not implement child_spec/1.

If you own the given module, please define a child_spec/1 function
that receives an argument and returns a child specification as a map.
For example:

    def child_spec(opts) do
      %{
        id: __MODULE__,
        start: {__MODULE__, :start_link, [opts]},
        type: :worker,
        restart: :permanent,
        shutdown: 500
      }
    end

Note that "use Agent", "use GenServer" and so on automatically define
this function for you.

However, if you don't own the given module and it doesn't implement
child_spec/1, instead of passing the module name directly as a supervisor
child, you will have to pass a child specification as a map:

    %{
      id: Friends.Repo,
      start: {Friends.Repo, :start_link, [arg1, arg2]}
    }

See the Supervisor documentation for more information.

            (elixir) lib/supervisor.ex:635: Supervisor.init_child/1
            (elixir) lib/enum.ex:1294: Enum."-map/2-lists^map/1-0-"/2
            (elixir) lib/supervisor.ex:621: Supervisor.init/2
            (elixir) lib/supervisor.ex:573: Supervisor.start_link/2
            (kernel) application_master.erl:273: :application_master.start_it_old/4
10:20:39.471 [info] Application friends exited with reason: #{'__exception__' => true,'__struct__' => 'Elixir.ArgumentError',message => <<"The module Friends.Repo was given as a child to a supervisor\nbut it does not implement child_spec/1.\n\nIf you own the given module, please define a child_spec/1 function\nthat receives an argument and returns a child specification as a map.\nFor example:\n\n    def child_spec(opts) do\n      %{\n        id: __MODULE__,\n        start: {__MODULE__, :start_link, [opts]},\n        type: :worker,\n        restart: :permanent,\n  ...">>} in 'Elixir.Supervisor':init_child/1 line 635
** (Mix) Could not start application friends: exited in: Friends.Application.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (ArgumentError) The module Friends.Repo was given as a child to a supervisor
but it does not implement child_spec/1.

If you own the given module, please define a child_spec/1 function
that receives an argument and returns a child specification as a map.
For example:

    def child_spec(opts) do
      %{
        id: __MODULE__,
        start: {__MODULE__, :start_link, [opts]},
        type: :worker,
        restart: :permanent,
        shutdown: 500
      }
    end

Note that "use Agent", "use GenServer" and so on automatically define
this function for you.

However, if you don't own the given module and it doesn't implement
child_spec/1, instead of passing the module name directly as a supervisor
child, you will have to pass a child specification as a map:

    %{
      id: Friends.Repo,
      start: {Friends.Repo, :start_link, [arg1, arg2]}
    }

See the Supervisor documentation for more information.

            (elixir) lib/supervisor.ex:635: Supervisor.init_child/1
            (elixir) lib/enum.ex:1294: Enum."-map/2-lists^map/1-0-"/2
            (elixir) lib/supervisor.ex:621: Supervisor.init/2
            (elixir) lib/supervisor.ex:573: Supervisor.start_link/2
            (kernel) application_master.erl:273: :application_master.start_it_old/4

What version of ecto are you using? It might be outdated.

Try replacing

  def start(_type, _args) do
    # List all child processes to be supervised
    children = [
      Friends.Repo
      # {Friends.Worker, arg},
    ]

with

def start(_type, _args) do
  import Supervisor.Spec

  # List all child processes to be supervised
  children = [
    supervisor(Friends.Repo, [])
    # {Friends.Worker, arg},
  ]

in https://github.com/dersar00/friends/blob/master/lib/friends/application.ex#L11

1 Like