I have the following controller in API which uses Phoenix.
defmodule TattooBackend.Web.API.V1.StudioController do
use TattooBackend.Web, :controller
alias TattooBackend.Accounts.Studio
def show(conn, %{"id" => id}) do
studio = Repo.get!(Studio, id)
render conn, studio: studio
end
end
My goal here is to rescue globally Ecto.NoResultsError and render some error message. I can rewrite this into following format:
def show(conn,%{"id" => id}) do
case Repo.get(Studio, id) do
nil -> # return null and 404
record -> # do something with record
end
end
but I want to avoid repeating this pattern in other controllers. How can I solve this problem?
1 Like
I believe it is already solved, and your original code should work just fine.
When Repo.get!
fails it raises Ecto.NoResultsError
as you may understand, and the phoenix_ecto
library already handles this error as 404.
In your app, you can handle this error at error_view.ex
. You should be having a function render('404.json', _assigns)
generated when you do mix phoenix.new
.
Note: the render('404.json', _assigns)
is only called when you’re running in Mix.env == :prod
. If the env is :dev
, you’ll be seeing Phoenix error page instead (but with the correct 404 status).
2 Likes
Just incase any other person has this issue, you could try:
- Add the following to your config/config.exs file
config :my_app, MyApp.Endpoint,
# ...
render_errors: [accepts: ~w(html json)],
# ...
- Disable debug_errors in you config/dev.exs file
config :my_app, MyApp.Endpoint,
# ...
debug_errors: false,
# ...
Credit: Thanks to Ole for his answer on Stackoverflow, https://stackoverflow.com/a/36334954
3 Likes