2016-04-26 65 views
0

我在我的應用程序中使用庫,它定期返回{:ok, value}{:error, error}的元組。在我們假設可能有錯誤(例如用戶輸入)的情況下,我們正在明確處理這些情況。對於所有其他情況,我寧願假設他們將得到妥善處理,如果沒有,則通過重定向處理失敗案例。我如何處理鳳凰城的全球自定義錯誤?

我開始嘗試用一個函數來解決這個問題:

def show(conn, %{"id" => id}) do 
    user = client.user_show(conn.assigns.endpoint, id) |> get_value(conn) 
    # rest of method omitted 
end 

def get_value({:ok, value}, _conn), do: value 

def get_value({:error, value}, conn) do 
    conn 
    |> put_flash(:error, "Client error") 
    |> redirect(to: "/") 
    |> halt 
end 

這似乎是個好主意,但不幸的是,在美國康涅狄格州仍在繼續,儘管停止。這是有道理的,因爲代碼路徑沒有分割。

所以看來更好的解決方案是實現此功能來引發特定的錯誤,然後嘗試全局解決它。

不幸的是,我找不到一種方法來處理菲尼克斯在全球範圍內的錯誤。我看到的唯一可能的選擇是使用ErrorView,但我不想只顯示錯誤,我想根據錯誤進行適當的重定向。

我錯過了什麼,或者目前在鳳凰城這是不可能的嗎?

回答

0

halt函數實際上並不提供任何分支邏輯。它只將conn的私人字段halted設置爲true。這可以確保其他插件不會進一步處理它,但其餘操作將處理它並覆蓋halted字段。

解決方案是將此功能移至插頭。

def client_error_plug(conn) do 
    user = client.user_show(conn.assigns.endpoint, id) |> get_value(conn) 
    case user do 
    {:ok, user} -> 
     assign(conn, :current_user, user) 
    {:error, reason} -> 
     conn 
     |> put_flash(:error, "Client error") 
     |> redirect(to: "/") 
     |> halt 
    end 
end 

,並在控制器只是把」

plug :client_error_plug when action in [:show, ...] 

這可能是有道理給這個插件更有意義的名稱,但是它依賴於應用程序的邏輯:)現在你可以確信你有用戶在分配,因爲如果它不在那裏,重定向將踢入。