2017-03-28 124 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