2

I’m having some trouble getting a simple example to work. I’m not using Phoenix FWIW, just plug

defmodule Unauthorized do
  defexception message: "not authorized", plug_status: 401
end

defmodule Foo do
  use Plug.Router
  plug :match
  plug :dispatch

  get "/" do
    send_resp(conn, 200, "heyyyo")
  end

  get "/boom" do
    raise Unauthorized
  end

  match _ do
    send_resp(conn, 404, "not found")
  end
end

This is kind of a silly example, but I’m just trying to see if it will work like I think it is supposed to work.

I was hoping that Plug would handle the exception raised in GET /boom and return a 401 status

However, when I do try to GET /boom it is returning a 500 status, so apparently the exception isn’t being handled by Plug

luk3thomas
  • 2,512
  • 1
  • 18
  • 20

1 Answers1

4

You need to add use Plug.ErrorHandler if you want to catch these exceptions and send an HTTP status code based on the exception that was raised:

defmodule Foo do
  use Plug.Router
  use Plug.ErrorHandler

  ...
end

With this change, I get the correct response:

$ curl -i http://localhost:4000/boom
HTTP/1.1 401 Unauthorized
server: Cowboy
date: Wed, 17 May 2017 19:59:57 GMT
content-length: 20
cache-control: max-age=0, private, must-revalidate

Something went wrong
Dogbert
  • 212,659
  • 41
  • 396
  • 397
  • a followup question for you. How do I test this? In the test I can only see it raises the exception. I'm not able to assert on `conn.status` – luk3thomas May 17 '17 at 20:25
  • 1
    You can use `Plug.Test.sent_resp`. Example from Plug's own tests: https://github.com/elixir-lang/plug/blob/master/test/plug/error_handler_test.exs#L36-L67. – Dogbert May 17 '17 at 20:39
  • Yep, that is it! – luk3thomas May 17 '17 at 20:40