HTTPoison not starting automatically with Elixir 1.4

Hi,

I’m reading and playing around the PragProg book Metaprogramming Elixir. In an example of the book “Code Generation from Remote APIs”, the book starts HTTPotion (I use HTTPoison instead) in the code. While this will work (also with HTTPoison), I’m trying to start it from the mix.exs file as I understand that’s the way it should be for external apps. But when I try to start the app from the mix.exs file, it fails with a hackney error (basically meaning HTTPoison is not started).

	== Compilation error on file lib/hub.ex ==
	** (exit) exited in: :gen_server.call(:hackney_manager, {:new_request, #PID<0.15
	3.0>, #Reference<0.0.3.894>, {:client, :undefined, {:metrics_ng, :metrics_dummy}
	, :hackney_ssl, 'api.github.com', 443, "api.github.com", [], nil, nil, nil, true
	, :hackney_pool, 5000, false, 5, false, 5, nil, nil, nil, :undefined, :start, ni
	l, :normal, false, false, false, :undefined, false, nil, :waiting, nil, 4096, ""
	, [], :undefined, nil, nil, nil, nil, :undefined, nil}}, :infinity)
	    ** (EXIT) no process: the process is not alive or there's no process current
	ly associated with the given name, possibly because its application isn't starte
	d
	    (stdlib) gen_server.erl:212: :gen_server.call/3
	    c:/Users/obou/Dropbox/Code/Elixir/hub/deps/hackney/src/hackney_manager.erl:6
	5: :hackney_manager.init_request/1
	    c:/Users/obou/Dropbox/Code/Elixir/hub/deps/hackney/src/hackney_manager.erl:5
	5: :hackney_manager.new_request/1
	    c:/Users/obou/Dropbox/Code/Elixir/hub/deps/hackney/src/hackney_connect.erl:1
	85: :hackney_connect.socket_from_pool/4
	    c:/Users/obou/Dropbox/Code/Elixir/hub/deps/hackney/src/hackney_connect.erl:3
	7: :hackney_connect.connect/5
	    c:/Users/obou/Dropbox/Code/Elixir/hub/deps/hackney/src/hackney.erl:328: :hac
	kney.request/5
	    lib/httpoison/base.ex:422: HTTPoison.Base.request/9
	    lib/httpoison.ex:66: HTTPoison.request!/5

My code is like this:

defmodule Hub do

  @username "chrismccord"

  #HTTPoison.start

  "https://api.github.com/users/#{@username}/repos"
  |> HTTPoison.get!(["User-Agent": "Elixir"])
  |> Map.get(:body)
  |> Poison.decode!
  |> Enum.each fn repo ->
    def unquote(String.to_atom(repo["name"]))() do
      unquote(Macro.escape(repo))
    end
  end

  def go(repo) do
    url = apply(__MODULE__, repo, [])["html_url"]
    IO.puts "Launching browser to #{url}..."
    System.cmd("open", [url])
  end
end

In my understanding, with Elixir 1.4 there is no longer a need to declare applications in the “applications” section of the mix.exs file, as long as an application is listed in the dependencies, Elixir 1.4 should figure out it has to start the application.

HTTPoison is declared in the dependencies of my mix file:

defp deps do
  [{:poison, "~> 3.0"},
    {:httpoison, "~> 0.10.0"}
end

I tried initially not adding :httpoison to the extra_applications list, and then adding it, both fail.

def application do
  # Specify extra applications you'll use from Erlang/Elixir
  [extra_applications: [:logger, :httpoison]]
end

As said, if I add HTTPoison.start at the top of my hub.ex script (Hub/lib/hub.ex), it works. But that’s not the way it should be, I should be able to start the HTTPoison from the mix.exs file.

I’m certainly doing something wrong, but I struggle finding what. By the way I’m on Windows 7, with OTP 19.3 and Elixir 1.4.2.

Any help is greatly appreciated, thanks !

Olivier.

HTTPoison hasn’t identified itself as an startable application as you can see in its mixfile:

The :mod-key is missing.

But as I read https://github.com/edgurgel/httpoison/issues/180, it feels as if it should work despite of this fact.

Perhaps there was even a regression in hackney, or something isn’t working correctly anymore when there are erlang deps involved? Can you please try to add :hackney as an :extra_application, try it with and without specifying :httpoison as well.

If I had to guess the issue is that you’re trying to use it in the module body at compile time. The application inferencing and extra_applications list are used to start application dependencies as runtime, not compile time.

1 Like

Ben, I think you’re spot on, HTTPoison or HTTPotion (got the same problem with both) is called at compile time to generate some functions on the fly. Did not realize that inferencing and extra_applications were not started at compile time. Now that makes sense. Ben, Norbert, thanks for your help!

A mod entry is not required to start the application. It can be started/stopped without the mod entry. The mod entry is only to start/stop a supervision tree.

Ah, OK, nice to know!