Reputation: 241
I'm trying to filter connections to my API.
In my mix.exs
I've added:
pipeline :some_validation do
plug VerifyLogicPlug
end
### INSIDE MY SCOPE:
pipe_through [:some_validation, :previous_pipeline]
My plug looks like this:
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
I get the desired response in the API:
{
"error": {
"title": "BLOCKED",
"status": 401,
"code": "BLOCKED"
}
}
But in the server I get some errors, depending on whether I use halt(conn)
or not.
With 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
Without 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
What I want (I think) is to use halt(conn)
but don't get the Plug.Conn.NotSentError
, as a response is being sent. Any hints on what's missing?
Thanks!
Upvotes: 0
Views: 823
Reputation: 6623
You are sending the response twice.
Change the respond_block
(which I suggest to rename to block_request
) to:
conn
|> put_resp_content_type("application/json")
|> send_resp(status, Poison.encode!(response))
|> halt()
Upvotes: 1