trabajo-afectivo/app/controllers/application_controller/handles_errors.rb

94 lines
3.1 KiB
Ruby
Raw Normal View History

module ApplicationController::HandlesErrors
extend ActiveSupport::Concern
included do
rescue_from StandardError, with: :internal_server_error
rescue_from ExecJS::RuntimeError, with: :internal_server_error
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActiveRecord::StatementInvalid, with: :unprocessable_entity
rescue_from ActiveRecord::RecordInvalid, with: :unprocessable_entity
rescue_from ActiveRecord::DeleteRestrictionError, with: :unprocessable_entity
rescue_from ArgumentError, with: :unprocessable_entity
rescue_from Exceptions::UnprocessableEntity, with: :unprocessable_entity
rescue_from Exceptions::NotAuthorized, with: :unauthorized
end
def not_found(e)
logger.error e
respond_to_exception(e, :not_found)
2017-08-21 23:13:19 +00:00
http_log
end
def unprocessable_entity(e)
logger.error e
respond_to_exception(e, :unprocessable_entity)
2017-08-21 23:13:19 +00:00
http_log
end
def internal_server_error(e)
logger.error e
respond_to_exception(e, :internal_server_error)
2017-08-21 23:13:19 +00:00
http_log
end
def unauthorized(e)
error = humanize_error(e.message)
response.headers['X-Failure'] = error.fetch(:error_human, error[:error])
respond_to_exception(e, :unauthorized)
2017-08-21 23:13:19 +00:00
http_log
end
private
def respond_to_exception(e, status)
status_code = Rack::Utils.status_code(status)
respond_to do |format|
format.json { render json: humanize_error(e.message), status: status }
format.any do
errors = humanize_error(e.message)
@exception = e
@message = errors[:error_human] || errors[:error] || param[:message]
@traceback = !Rails.env.production?
file = File.open(Rails.root.join('public', "#{status_code}.html"), 'r')
render inline: file.read, status: status
end
end
end
def humanize_error(error)
data = {
error: error
}
case error
when /Validation failed: (.+?)(,|$)/i
data[:error_human] = $1
when /(already exists|duplicate key|duplicate entry)/i
data[:error_human] = 'Object already exists!'
when /null value in column "(.+?)" violates not-null constraint/i
data[:error_human] = "Attribute '#{$1}' required!"
when /Field '(.+?)' doesn't have a default value/i
data[:error_human] = "Attribute '#{$1}' required!"
when 'Exceptions::NotAuthorized'
data[:error] = 'Not authorized'
data[:error_human] = data[:error]
end
if Rails.env.production?
if data[:error_human].present?
data[:error] = data.delete(:error_human)
else
# We want to avoid leaking of internal information but also want the user
# to give the administrator a reference to find the cause of the error.
# Therefore we generate a one time unique error ID that can be used to
# search the logs and find the actual error message.
error_code_prefix = "Error ID #{SecureRandom.urlsafe_base64(6)}:"
Rails.logger.error "#{error_code_prefix} #{data[:error]}"
data[:error] = "#{error_code_prefix} Please contact your administrator."
end
end
data
end
end