I'm building a Rails 5 API and trying to handle the error response when a record is not found (i.e. /v1/users/99
but that user does not exist).
I'm using Active Model Serializer for serialization and I'm thinking there must be a way to only show the status and the error, not the stack trace. Right now, I get this:
{
status: 404,
error: "Not Found",
exception: "#<ActiveRecord::RecordNotFound: Couldn't find User with 'id'=99>",
traces: {
Application Trace: [
{
id: 1,
trace: "app/controllers/api/v1/users_controller.rb:45:in `set_user'"
}
],
Framework Trace: [
{
id: 0,
trace: "activerecord (5.0.2) lib/active_record/core.rb:173:in `find'"
},
{
id: 2,
trace: "activesupport (5.0.2) lib/active_support/callbacks.rb:382:in `block in make_lambda'"
},
{
id: 3,
trace: "activesupport (5.0.2) lib/active_support/callbacks.rb:150:in `block (2 levels) in halting_and_conditional'"
},
{
id: 4,
trace: "actionpack (5.0.2) lib/abstract_controller/callbacks.rb:12:in `block (2 levels) in <module:Callbacks>'"
},
{
id: 5,
trace: "activesupport (5.0.2) lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'"
},
.
.
.
I want the error to simple on the API side, just status and error. How can this be done?
I've been doing this for logging and printing different messages in different environments.
class ApplicationController < ActionController::API
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found_rescue
def record_not_found_rescue(exception)
logger.info("#{exception.class}: " + exception.message)
if Rails.env.production?
render json: {}, status: :not_found
else
render json: { message: exception, backtrace: exception.backtrace }, status: :not_found
end
end
end
I found this to be useful not only to not print back traces but you now don't need an if statement in every single controller action.
It couples well with finder methods in your controller.
def show
user = find_user
render json: user , status: :ok
end
private
def find_user
User.find(params[:id])
end
Remember you can handle different types of exceptions like this, not only the ActiveRecord::RecordNotFound
.