Thanks for your reply José.
The thing is, this exception didn't happen before when I was using "application/json" as "accept" request header.
Let me clarify:
This morning I changed my application so that it now requires "application/vnd.api+json" as "accept" request header instead of "application/json". As soon as I did the change, Phoenix started to throw this exception in 404 scenario. I have checked out the previous version to confirm this and it is the case, Phoenix did not throw any exception when handling a 404 using "application/json".
What have I changed to require "application/vnd.api+json"?
1. Added this to my config.exs
config :plug,
:mimes, %{"application/vnd.api+json" => ["json-api"]}
2. In my endpoint.ex module, replaced `plug :accepts, ["json"]` with `plug :accepts, ["json-api"]`
3. In error_view.ex, replaced "400.json" with "400.json-api" (as it shows in the Gist I posted earlier)
4. In error_view.ex, the render/2 function used to return an empty map %{}, but this was crashing now (as in, causing a 500):
#PID<0.388.0> running FacebookService.Endpoint terminated
Server: localhost:4001 (http)
Request: GET /oops
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Plug.Conn.resp/3
(plug) lib/plug/conn.ex:434: Plug.Conn.resp(%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{correlation_id: "1234", correlation_id_presence_failed?: false, kind: :error, layout: false, reason: %Phoenix.Router.NoRouteError{conn: %Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{correlation_id: "1234", correlation_id_presence_failed?: false, request_reception_timestamp: {1432, 561479, 57438}}, before_send: [#Function<0.101105578/1 in HTTPex.Plugs.HTTPLogger.call/2>], body_params: %{}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "GET", owner: #PID<0.388.0>, params: %{"format" => "json-api"}, path_info: ["oops"], peer: {{127, 0, 0, 1}, 56063}, port: 4001, private: %{phoenix_endpoint: FacebookService.Endpoint, phoenix_pipelines: [], phoenix_router: FacebookService.Router}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"accept", "application/vnd.api+json"}, {"shim-correlation-id", "1234"}, {"user-agent", "hackney/1.1.0"}, {"host", "localhost:4001"}], resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}], scheme: :http, script_name: [], secret_key_base: "mcV+tU17meac6XZ+cvGLaV5+By4XXr24wR87fTTUVLy/G6w+E4umFDLYe72cBA5J", state: :unset, status: nil}, message: "no route found for GET /oops (FacebookService.Router)", plug_status: 404, router: FacebookService.Router}, request_reception_timestamp: {1432, 561479, 57438}, stack: [{FacebookService.Router, :match, 4, [file: 'web/router.ex', line: 1]}, {FacebookService.Router, :call, 2, [file: 'lib/phoenix/router.ex', line: 2]}, {FacebookService.Endpoint, :phoenix_endpoint_pipeline, 1, [file: 'lib/facebook_service/endpoint.ex', line: 1]}, {FacebookService.Endpoint, :call, 2, [file: 'lib/phoenix/endpoint/render_errors.ex', line: 34]}, {Phoenix.Endpoint.CowboyHandler, :upgrade, 4, [file: 'lib/phoenix/endpoint/cowboy_handler.ex', line: 52]}, {:cowboy_protocol, :execute, 4, [file: 'src/cowboy_protocol.erl', line: 435]}]}, before_send: [#Function<0.101105578/1 in HTTPex.Plugs.HTTPLogger.call/2>], body_params: %{}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "GET", owner: #PID<0.388.0>, params: %{"format" => "json-api"}, path_info: ["oops"], peer: {{127, 0, 0, 1}, 56063}, port: 4001, private: %{phoenix_endpoint: FacebookService.Endpoint, phoenix_layout: false, phoenix_pipelines: [], phoenix_router: FacebookService.Router, phoenix_template: "404.json-api", phoenix_view: FacebookService.ErrorView}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"accept", "application/vnd.api+json"}, {"shim-correlation-id", "1234"}, {"user-agent", "hackney/1.1.0"}, {"host", "localhost:4001"}], resp_body: nil, resp_cookies: %{}, resp_headers: [{"content-type", "application/vnd.api+json; charset=utf-8"}, {"cache-control", "max-age=0, private, must-revalidate"}], scheme: :http, script_name: [], secret_key_base: "mcV+tU17meac6XZ+cvGLaV5+By4XXr24wR87fTTUVLy/G6w+E4umFDLYe72cBA5J", state: :unset, status: 404}, 404, %{})
(plug) lib/plug/conn.ex:424: Plug.Conn.send_resp/3
(phoenix) lib/phoenix/endpoint/cowboy_handler.ex:52: Phoenix.Endpoint.CowboyHandler.upgrade/4
(cowboy) src/cowboy_protocol.erl:435: :cowboy_protocol.execute/4, now it returns a conn (
Why does this crash after I changed from "application/json" to "application/vnd.api+json"? This is really my question.
Anyway, user voltone from #elixir-lang suggested I call Phoenix.Controller.json(%{})) instead of returning %{}. That helped with returning the 404, but Phoenix still threw an exception.