alex
alex

Reputation: 331

How to add attributes to json exception response in rails 5

When I call a service in my api REST app for example "localhost/api/boxes/56" with an id value who doesn't exists in my data base I get a RecordNotFoundException and the json rendered looks like:

{
  "status": 404,
  "error": "Not Found",
  "exception": "#<ActiveRecord::RecordNotFound: Couldn't find Box with 'id'=56>",
  "traces": {
    "Application Trace": [
      {
        "id": 1,
        "trace": "app/controllers/api/v1/boxes_controller.rb:47:in `set_box'"
      }
    ],
    "Framework Trace": [
      {
        "id": 0,
        "trace": "activerecord (5.0.2) lib/active_record/core.rb:173:in `find'"
      },...
    ],
    "Full Trace": [
      {
        "id": 0,
        "trace": "activerecord (5.0.2) lib/active_record/core.rb:173:in `find'"
      },...
    ]
  }
}

How and what class have I to override to add a "message" attribute in this exception?

Upvotes: 1

Views: 395

Answers (1)

Sebasti&#225;n Palma
Sebasti&#225;n Palma

Reputation: 33420

You can handle if the record isn't found through your own validation, if you're trying to get a record in your database through the id or any other maybe as:

record = Record.find(params[:id])

Then you can check if that record is nil, because it couldn't be found, maybe a bad request, then render the json as you want, something like:

if !record.nil?
  render json: record, status: 200
else
  render json: bad_request
end

And the bad_request method is defined within the ApplicationController like:

def bad_request
  {
    error: 'Record not found, maybe a bad request',
    status: 400
  }
end

Or if in the other hand, you want to handle and set your own response to that behavior directly on your method which is being fired then you can rescue the ActiveRecord::RecordNotFound exception, like:

def show
  box = Box.find(params[:id])
  render json: box, status: 200
rescue ActiveRecord::RecordNotFound
  render json: { error: 'Baaaaaad' }
end

Also if you want to make this action available for all your models you can use the rescue_from method within your ApplicationController and to set the exception to "catch" and then the method which will respond with, like:

class ApplicationController < ActionController::Base
  ...
  rescue_from ActiveRecord::RecordNotFound, with: :damn_nothing_found

  def damn_nothing_found
    render json: { error: 'nothing found :c' }, status: :not_found
  end
end

Upvotes: 2

Related Questions