模式匹配HTTPoison.Response

时间:2017-11-13 04:12:31

标签: elixir

我正在尝试使用HTTPoison处理来自API调用的响应

在我的应用环境中,我有

def add_to_cart(data, user) do
  case HTTPoison.post!(
      "https://api.moltin.com/v2/carts/" <> user <> 
      "/items", data,
      [{"Authorization",
        "Bearer #{Agent.get(:token, fn state -> state end)}"},
       {"Content-Type", "application/json"}] do

    {:ok, %HTTPoison.Response{status_code: 201, body: body}} ->
      case Poison.decode(body) do
        {:ok, decoded} -> decoded
        {:error, error} -> {:error, error}
      end

    {:ok, %HTTPoison.Response{status_code: 404}} ->
      IO.puts "Not found :("

    {:error, %HTTPoison.Error{reason: reason}} ->
      IO.inspect reason

  end
end

我返回的错误是:

CaseClauseError at POST /order
no case clause matching: %HTTPoison.Response{response content}

我在我的代码中的其他地方使用了这种模式,它匹配得很好但是当我把它放在这里时,它似乎不起作用。

我确信这不足以使用哪些信息,但我现在还不确定还有什么可以放的。任何指导都将不胜感激。

3 个答案:

答案 0 :(得分:6)

Elixir惯例是:函数的撞击版本 - 而不是{:ok, result}{:error, reason} - 成功时返回result并引发错误。 Grep this page表示“Elixir没有强制例外”作为参考。

HTTPoison follows this convension

要使代码正常工作,应该在最佳情况下使用HTTPoison.post绑定),或分别匹配结果:

try
  %HTTPoison.Response{status: status, body: body} = HTTPoison.post!(...)
  case status do
    201 -> ...
    404 -> ...
  end
rescue
  e in HTTPoison.Error ->
    IO.inspect e
end  

答案 1 :(得分:2)

HTTPoison docs建议的一个漂亮而优雅的模式匹配怎么样?只需摆脱感叹号并尝试这样的事情:

case HTTPoison.post(stuff) do
  {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
    decoded_stuff = Poison.decode(body) # use another nice case statement here
  {:ok, %HTTPoison.Response{status_code: 404}} ->
    IO.puts "Not found :("
  {:error, %HTTPoison.Error{reason: reason}} ->
    IO.inspect reason
end

答案 2 :(得分:1)

根据该错误消息,您不需要元组中的:ok:error个原子,请尝试更改它们:

{:ok, %HTTPoison.Response{status_code: 201, body: body}} -> #...
{:error, %HTTPoison.Error{reason: reason}} -> #...

要:

%HTTPoison.Response{status_code: 201, body: body} -> #...
%HTTPoison.Error{reason: reason} -> #...

我认为在您的应用中的其他位置,您可能正在使用post/4而不是post!/4post/4(没有!)返回带有{{1}的元组}} {}} {} {}} {} {}} {}} {}} {}} {}} {}} {}} {}} {}} {