2016-04-26 4 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 

これは良いアイデアのように思えたが、残念ながら、CONNはまだ停止にもかかわらず、続けていました。コードパスが分割されなかったため、これは意味があります。

したがって、この関数を実装して特定のエラーを発生させ、それをグローバルに解決しようとする方がよいでしょう。

残念ながら、私はフェニックスのグローバルレベルでエラーを処理する方法を見つけることができません。私が見る唯一の可能なオプションはErrorViewですが、エラーを表示するだけではなく、エラーに応じて適切にリダイレクトします。

フェニックスには何かがないか、これは現在できませんか?

答えて

0

halt関数は、実際には分岐ロジックを提供しません。 connのプライベートフィールドhaltedtrueに設定されています。これにより、他のプラグはそれ以上処理しませんが、アクションの残りの部分はそれを処理して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, ...] 

を置くこれはおそらく、このプラグインにもっと意味のある名前を与えることは理にかなっていますが、それはアプリケーションのロジックに依存します:)今、あなたはあなたのことを確認することができます割り当てられていない場合はリダイレクトが実行されるため、ユーザを割り当ててください。

関連する問題