16
votes

In my Phoenix JSON API I am getting an Ecto NoResultsError when I request an object that doesn't exist in the database.

I want my JSON API to return a null along with a 404 error.

How would I do this?

Currently I pretty much have a default generated html controller/views etc. I have modified the controller like this:

def show(conn, %{"id" => id}) do
  my_model = Repo.get!(MyModel, id)
  case get_format(conn) do
    "json" ->
      render(conn, my_model: my_model)
    _ ->
      render(conn, "show.html", my_model: my_model)
  end
end

along with the view:

defmodule MyProject.MyModelView do
  use Laired.Web, :view

  def render("show.json", %{my_model: my_model}) do
    my_model
  end
end

Related:

Setting up custom response for exception in Phoenix Application

2

2 Answers

20
votes

Use get instead of get! and handle the logic when it returns nil:

def show(conn,%{"id" => id}) do
  case Repo.get(MyModel, id) do
    nil -> # return null and 404 
    record -> # do something with record        
  end
end  
4
votes

Can catch the error using try, rescue as well

def show(conn,%{"id" => id}) do
    try do
      result =
        Repo.get!(MyModel, id)

      {:ok, result}
    rescue
      Ecto.NoResultsError ->
        {:error, :not_found, "No result found"}
    end
end