Dialyzer does not know :httpc

I am working on Elixir, using Erlang built-in :httpc function to perform a get request.

defp get_gravatar(primary_email, userid) do
    hash =
      primary_email
      |> String.trim()
      |> String.downcase()
      |> :erlang.md5()
      |> Base.encode16(case: :lower)

    Application.ensure_all_started(:inets)
    Application.ensure_all_started(:ssl)

    img = 'https://www.gravatar.com/avatar/#{hash}?s=150&d=404'

    if {:ok, {status, header, body}} = :httpc.request(:get, {img, []}, [], []) do
      case status do
        {_, 404, 'Not Found'} ->
          nil

        {_, 200, 'OK'} ->
          content_type = find_content_type(header) |> to_string
          filextension = String.replace(content_type, "image/", "")
          filename = "original.#{filextension}"
          path = "#{Application.get_env(:vutuv, :storage_dir)}" <> "#{userid}/"
          File.write(path <> filename, body)

          _upload = %{
            file_name: filename,
            updated_at: NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
          }

        true ->
          nil
      end
    end
  end

  defp find_content_type(header) do
    Enum.reduce(header, fn {k, v}, acc ->
      if k == 'Content-Type' or k == 'content-type', do: v, else: acc
    end)
  end

Dialyzer complains there are two errors:

:0:unknown_function
Function :httpc.request/4 does not exist.
________________________________________________________________________________
lib/vutuv/accounts.ex:301:guard_fail
Guard test:
_ :: {:ok, {_, _, _}}

===

false

can never succeed.
________________________________________________________________________________
done (warnings were emitted)

After adding this lines to the modules,

@dialyzer {:nowarn_function, get_gravatar: 2}

the first error still persists

:0:unknown_function
Function :httpc.request/4 does not exist.
________________________________________________________________________________
done (warnings were emitted)

You might need to add the :httpc app to the dialyzer config in your mix.exs. For example:

  def project do
    [
      ,,,
      dialyzer: [
        plt_add_apps: ~w(httpc)a
      ],
      ...
    ]
  end
1 Like

Have you listed :httpc under :extta_applications in your mix.exs?

:httpc is under :inets application

3 Likes

After adding :inets to the extra_applications in mix.exs, everything is passed successfully.

Thank you for all responses, very helpful.

4 Likes