我正在尝试使用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}
我在我的代码中的其他地方使用了这种模式,它匹配得很好但是当我把它放在这里时,它似乎不起作用。
我确信这不足以使用哪些信息,但我现在还不确定还有什么可以放的。任何指导都将不胜感激。
答案 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!/4
,post/4
(没有!
)返回带有{{1}的元组}} {}} {} {}} {} {}} {}} {}} {}} {}} {}} {}} {}} {}} {