Reputation: 255
I build restful api (json) on phoenix. And I did not need the support of html.
How to override errors in phoenix? Example errors: - 500 - 404 when no route found and other.
Upvotes: 10
Views: 3696
Reputation: 54734
You need to customize MyApp.ErrorView
. Phoenix generates this file for you in web/views/error_view.ex. The default content of the template can be found on Github.
Also see the docs on custom errors, although they seem to be a bit outdated because they instruct you to use MyApp.ErrorsView
(plural), which was replaced with MyApp.ErrorView
Upvotes: 4
Reputation: 307
None of the answer above worked for me.
The only way i was able to make phoenix use json
only for the api endpoint was to edit the endpoint settings this way :
config :app, App.Endpoint,
render_errors: [
view: App.ErrorView,
accepts: ~w(json html) # json has to be in before html otherwise only html will be used
]
The idea being json has to be the first of the world list for html to be rendered, kinda weird but it works.
Then have an ErrorView which looks like this :
defmodule App.ErrorView do
use App, :view
def render("400.json", _assigns) do
%{errors: %{message: "Bad request"}}
end
def render("404.json", _assigns) do
%{errors: %{message: "Not Found"}}
end
def render("500.json", _assigns) do
%{errors: %{message: "Server Error"}}
end
end
Nothing different from the other answer here, I just added a 400 bad request because I ran into it and you should too : add anything that you might run into.
And finally in my router code:
pipeline :api do
plug(:accepts, ["json"])
end
pipeline :browser do
plug(:accepts, ["html"])
...
end
Nothing different from the other answer but you have to make sure your pipelines are configured correctly.
Upvotes: 1
Reputation: 109
You can override 400-500 errors with plug :accepts, ["json"]
in you router.ex
. For example:
# config/config.exs
...
config :app, App.endpoint,
...
render_errors: [accepts: ~w(html json)],
...
# web/views/error_view.ex
defmodule App.ErrorView do
use App.Web, :view
def render("404.json", _assigns) do
%{errors: %{message: "Not Found"}}
end
def render("500.json", _assigns) do
%{errors: %{message: "Server Error"}}
end
end
# in router.ex
defmodule App.Router do
use App.Web, :router
pipeline :api do
plug :accepts, ["json"]
end
pipe_through :api
# put here your routes
post '/foo/bar'...
# or in scope:
scope '/foo' do
pipe_through :api
get 'bar' ...
end
It will works.
Upvotes: 0
Reputation: 2445
For those who may have the same issues I had, there a couple of steps required to render JSON for 404 and 500 responses.
Firstly add render("404.json", _assigns)
and render("500.json", _assigns)
to your app's web/views/error_view.ex
file.
For example:
defmodule MyApp.ErrorView do
use MyApp.Web, :view
def render("404.json", _assigns) do
%{errors: %{message: "Not Found"}}
end
def render("500.json", _assigns) do
%{errors: %{message: "Server Error"}}
end
end
Then in your config/config.exs
file updated the default_format
to "json"
.
config :my_app, MyApp.Endpoint,
render_errors: [default_format: "json"]
Note that if your app is purely a REST api this will be fine, but be careful in the event you also render HTML responses as now by default errors will be rendered as json.
Upvotes: 8