How does one default a scope to render errors as JSON? Currently it seems to default to html, thus whenever an error occurs it’s renderring XXX.html
.
How about data, I suppose json/2 is the way to go when sending a response back to the client?
How does one default a scope to render errors as JSON? Currently it seems to default to html, thus whenever an error occurs it’s renderring XXX.html
.
How about data, I suppose json/2 is the way to go when sending a response back to the client?
It defaults to rendering whatever you return. ^.^
If you want to, say, render a different error style based on the format, well you can check the requested format and return a specialized return body (defaulting to whatever).
What I am aiming for is having an /api
endpoint (or scope) that returns regular data or a message in case there was an error, both as JSON.
Currently any error raising inside the api scope is being renderred as its .html version, is it possible to configure the scope to instead do .json? perhaps a way to catch any error happening inside a scope? any other approach?
In the config/config.exs file, there is a render_errors entry (for your app’s config). Make sure it has accepts ~w(json)
, and not accepts ~w(html json)
.
Be aware though that some response codes are limited to return HTML as per rfc. I had to look those up though
I’ve been struggling with the same problem for the past couple of hours. As far as my knowledge goes, using accepts ~w(json)
in your endpoint configuration is useless as you want to render HTML and JSON depending on the scope.
Hovewer, the following works for me:
Use :api
pipeline for your /api
scope
pipeline :api do
plug :accepts, ["json"]
end
scope "/api", as: :api do
pipe_through [:api]
...
end
Define functions for any of the errors (404, 500, etc.) you want to render as JSON in your project’s ErrorView
def render("404.json", _assings) do
%{errors: %{message: "Resource not found"}}
end
Finally, make sure that requests to your API have Accept
header field set to application/json
.
Please note that I’m a Phoenix/Elixir beginner. I’m not familiar with any solution that would allow us to enforce JSON responses for common errors (404, 500) per scope, no matter what is the Accept
header field’s value.
Any comments and suggestions for possible improvements are more than welcome.
I have been doing a bit of research through Phoenix’ source code and found out:
format
param here.accepts
plug is invoked.Now, before raising an error in a controller, I am able to confirm phoenix_format
is set to json. What happens next is it tries to render the error but with the format being html instead.
Therefore, Phoenix might be ignoring the changes made to the Plug.Conn
structure when the plug pipeline halts somewhere. Here goes a gist for reference.
As I recall (I may be wrong) but the HTML spec requires HTML to be sent on many error status codes (don’t recall which ones off hand).