Alexey Egorov
Alexey Egorov

Reputation: 2400

HTTPoison ArgumentError on Phoenix mix task

I have mix task mix fetch.btc on phoenix app (lib/mix/tasks/fetch.btc.ex):

defmodule Mix.Tasks.Fetch.Btc do
  use Mix.Task

  def run(_args) do
    res = HTTPoison.get!("https://blockchain.info/ticker")
    IO.inspect(res)
  end
end

When I run mix fetch.btc I got error:

** (ArgumentError) argument error
    (stdlib) :ets.lookup_element(:hackney_config, :mod_metrics, 2)
    PROJ_DIR/deps/hackney/src/hackney_metrics.erl:27: :hackney_metrics.get_engine/0
    PROJ_DIR/deps/hackney/src/hackney_connect.erl:78: :hackney_connect.create_connection/5
    PROJ_DIR/deps/hackney/src/hackney_connect.erl:47: :hackney_connect.connect/5
    PROJ_DIR/deps/hackney/src/hackney.erl:330: :hackney.request/5
    lib/httpoison/base.ex:787: HTTPoison.Base.request/6
    lib/httpoison.ex:128: HTTPoison.request!/5
    lib/mix/tasks/fetch.btc.ex:14: Mix.Tasks.Fetch.Btc.run/1
    (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:79: Mix.CLI.run_task/2
    (elixir) lib/code.ex:767: Code.require_file/2

But in my controller this code res = HTTPoison.get!("https://blockchain.info/ticker") is work success!

Info:

hackney: 1.15.1
httpoison: 1.5.0
phoenix: 1.4.3
  1. What am I doing wrong?
  2. What is right way make http request in mix task?

Upvotes: 2

Views: 632

Answers (3)

Ruan Nawe
Ruan Nawe

Reputation: 460

Add the following code to the file /test/test_helper.exs

# /test/test_helper.exs
ExUnit.start()
HTTPoison.start() # YOUR CODE HERE
Ecto.Adapters.SQL.Sandbox.mode(SocialNetworks.Repo, :manual)

Upvotes: 0

Zubair Nabi
Zubair Nabi

Reputation: 1046

You can also use HTTPoison.start() before the actual call. That will also work, if you dont want to start the hackney application every time in mix file or if you do not want to start using Application.

Upvotes: 2

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 120990

The code in you controller runs when the application and all it’s dependencies are already started. mix tasks are run within :mix application which obviously does not start :hackney by default.

All you need is to ensure it’s started / start it manually:

def run(_args) do
  # ⇓⇓⇓⇓⇓⇓⇓ THIS ⇓⇓⇓⇓⇓⇓⇓
  Application.ensure_all_started(:hackney)
  # ⇑⇑⇑⇑⇑⇑⇑ THIS ⇑⇑⇑⇑⇑⇑⇑

  res = HTTPoison.get!("https://blockchain.info/ticker")
  IO.inspect(res)
end

Upvotes: 5

Related Questions