2017-08-01 34 views
0

我正在嘗試過濾連接到我的API。使用插件過濾API連接

在我mix.exs我說:

pipeline :some_validation do 
    plug VerifyLogicPlug 
end 

### INSIDE MY SCOPE: 

    pipe_through [:some_validation, :previous_pipeline] 

我的插件看起來像這樣:

defmodule VerifyLogicPlug do 

    import Plug.Conn 

    def init(options), do: options 

    def call(conn, _options) do 
    if some_logic do 
     respond_blocked(conn) 
    else 
     conn # Continue the normal execution of the pipeline 
    end 
    end 

    defp respond_blocked(conn) do 
    response = %{ 
     error: %{ 
     status: 401, 
     code: "BLOCKED", 
     title: "BLOCKED" 
     } 
    } 

    conn 
    |> put_resp_content_type("application/json") 
    |> send_resp(status, Poison.encode!(response)) 
    halt(conn) # I've tried both with and without this line 
    end 
end 

我得到的API中所需的響應:

{ 
    "error": { 
     "title": "BLOCKED", 
     "status": 401, 
     "code": "BLOCKED" 
    } 
} 

但在服務器我得到一些錯誤,這取決於我是否使用halt(conn)或不。 隨着halt(conn)

[error] #PID<0.1003.0> running MyProject.Endpoint terminated 
Server: localhost:4000 (http) 
Request: GET (...) 
** (exit) an exception was raised: 
    ** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection 

沒有halt(conn)

[error] #PID<0.1404.0> running MyProject.Endpoint terminated 
Server: localhost:4000 (http) 
Request: GET (...) 
** (exit) an exception was raised: 
    ** (Plug.Conn.AlreadySentError) the response was already sent 

我想(我認爲)是使用halt(conn)但沒有得到Plug.Conn.NotSentError,如正在發送的響應。有什麼提示缺少什麼?

謝謝!

回答

1

您正在發送回覆兩次。

更改respond_block(我建議重命名爲block_request)到:

conn 
|> put_resp_content_type("application/json") 
|> send_resp(status, Poison.encode!(response)) 
|> halt() 
+0

哦,我明白了!所以區別在於我的代碼中,我正在使用'conn'作爲參數'halt',而在你的''conn'中,我們正在通過管道修改'halt'。新手錯誤,我想。謝謝! – Alan

+0

很難準確地說出是哪個問題,因爲我需要查看應用程序的其他部分。您可能想要查看此處的Plug.Conn源代碼,以瞭解如何引發AlreadySentError:https://github.com/elixir-plug/plug/blob/v1.4.3/lib/plug/conn.ex#L388 –