Skip to content

Instantly share code, notes, and snippets.

@fespinoza
Created November 30, 2015 20:46
Show Gist options
  • Save fespinoza/3c75877aedccef709dde to your computer and use it in GitHub Desktop.
Save fespinoza/3c75877aedccef709dde to your computer and use it in GitHub Desktop.
Error Normalization Concern
module ErrorNormalization
extend ActiveSupport::Concern
included do
rescue_from CanCan::AccessDenied, with: :render_forbidden
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
rescue_from ActionController::ParameterMissing, with: :render_bad_request
end
def render_forbidden
build_and_render_api_error(403, :forbidden)
end
def render_not_found(exception)
message = normalize_not_found_message(exception)
build_and_render_api_error(404, :not_found, message: message)
end
def render_bad_request(exception)
build_and_render_api_error(400, :bad_request, message: exception.message)
end
def render_show_or_errors(object, status: 200)
respond_to do |format|
format.json do
if object.valid?
render :show, status: status
else
render_api_error(build_validation_error(object))
end
end
end
end
def build_validation_error(object)
options = { validation_errors: object.errors }
build_api_error(422, :unprocessable_entity, options)
end
def build_api_error(status_code, error_identifier, options = {})
options[:subdomain] ||= organization_identifier
API::Error.new(status_code, error_identifier, options)
end
def render_api_error(api_error)
render json: api_error, status: api_error.status
end
def build_and_render_api_error(status_code, error_identifier, options = {})
api_error = build_api_error(status_code, error_identifier, options)
render_api_error(api_error)
end
private
def normalize_not_found_message(exception)
message = exception.message
match = message.match(/Couldn't find (?<class_name>[^\s]+)/)
if match
class_name = match[:class_name].split('::').last
message = I18n.t :not_found,
scope: [:api, :errors, :messages],
class_name: class_name
end
message
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment