“透析通常是永远没有错”,但我想不出我@spec如何是不正确(“Dialyzer is usuall

2019-10-29 05:46发布

我有一些代码,失败透析,我不明白为什么。 不管我怎么投入@spec在函数的顶部,则调用该函数返回一个令人费解的透析器错误。 下面是功能的简化。 至于我可以告诉大家,我只具备正确的功能。

@spec balances(uuid :: String.t(), retries :: non_neg_integer) ::
        {:ok, list()}
        | {:internal_server_error, String.t(), String.t()}
        | {:internal_server_error, map | list, String.t()}
def balances(uuid, retries \\ 0) do
  url = "/url/for/balances" |> process_url

  case HTTPoison.get(
         url,
         [, {"Content-Type", "application/json"}],
         []
       ) do
    {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
      response = Poison.decode!(body, as: %{"message" => [%Currency{}]})

      cond response["message"] do
        length(bal) > 0 ->
          {:ok, bal}

        retries >= 1 ->
          {:ok, []}

        true ->
          init(uuid)
          balances(uuid, retries + 1)
      end

    {:error, %HTTPoison.Error{reason: reason}} ->
      Notifier.notify(url, reason, Helpers.line_info(__ENV__))
      {:internal_server_error, reason, url}

    {_, %HTTPoison.Response{body: body} = res} ->
      response = Poison.decode!(body)
      Notifier.notify(url, response, Helpers.line_info(__ENV__))

      {:internal_server_error, response, url}
  end
end

我的问题是,如果我希望得到任何其他比整个代码库每次调用这个函数失败{:ok, balances}

  user_balances =
    case balances(uuid) do
      {:ok, user_balances} -> user_balances
      _ -> [] # Dialyzer error here
    end

透析器警告The variable _ can never match since previous clauses completely covered the type {'ok',[map()]} 我读这意味着,以平衡任何调用将始终返回{:ok, balances} ,但作为case语句是不是真的HTTPoison.get是在功能评估的最后一件事,看来只有有三种可能的结果:

  • {:ok, list}
  • {:internal_server_error, String.t(), String.t()}
  • {:internal_server_error, map | list, String.t()} {:internal_server_error, map | list, String.t()}

我明白,我可能失去了一些东西很明显,但我无法弄清楚它是什么。 任何帮助将不胜感激。 谢谢!

Answer 1:

感谢@ legoscia的评论,我调查了呼叫Notifier.notify ,果然有该功能的透析器的警告,以及(我有PR了一个开源项目来解决,导致该通知功能失效的规范透析器)。 如果我修改了通知功能,使得没有报警时,果然在两个电话balances不再产生透析器的警告。

TL;医生如果透析器为您提供了有关不会出现被错误地规定,开始经历你的函数中的函数调用找到下游透析器误差函数警告。



文章来源: “Dialyzer is usually never wrong”, but I can't figure out how my @spec is incorrect