2017-03-28 34 views
1

假设你有以下功能:管道和错误处理

def get_city_temp(city_id) do 
    'blahblahcityforcastfortoday.com/request/#{city_id}' 
    |> HTTPoison.get 
    |> parse_body 
    |> get_forecast 
    |> get_temp 
end 

现在说GET失败,所以响应是:

{:ok, %HTTPoison.Response{status_code: 400, ...}} 

get_forecast是期待一个良好成型体,和因此会错误地抱怨传递给它的结构或缺失的键等等。处理这种错误的最佳方法是什么?在其他语言中,我只包含trycatch s中的所有函数调用,并返回包含成功报告的元组。在这种情况下,我不确定如何构建我的代码以最好地向用户报告错误 。

回答

5

这正是with/1宏的意思。假设parse_body等功能也以失败返回{:ok, _}成功和{:error, _},你可以这样做:

with {:ok, response} <- HTTPoison.get(...), 
    {:ok, parsed} <- parse_body(response), 
    {:ok, forecast} <- get_forecast(parsed), 
    {:ok, temp} <- get_temp(forecast), do: {:ok, temp} 

如果任一个模式匹配失败,这整个事情的返回值。例如,如果get_forecast在所有前面的函数返回{:ok, _}后返回{:error, :foo},则with将返回{:error, :foo}

+0

非常好的解释,谢谢 – category

+4

唯一的问题是,'='应该替换成'<-',否则在匹配时会因为问题而'上升'。除此之外,这是要走的路! –

+2

@PawełDawczak修好了,谢谢! – Dogbert