I'm trying to send all rails errors as a notification, without disturbing other rescues.
ApplicationController:
class ApplicationController < ActionController::Base
around_filter :notify_errors
def notify_errors
begin
yield
rescue => e
Notification.send_to(:admin, e)
end
end
end
SomeController function:
def send_date
date = Date.strptime('10/100/2013', '%m/%d/%Y')
render json: {success: true, date: date}
rescue ArgumentError
render json: {success: false, msg: 'Bad date'}
end
I get the "Bad date" json but not the Notification.send_to(:admin, e)
.
Is there a way to make it easier for each reraise error? A global solution or a function?
You could monkeypatch raise
.
module RaiseNotify
def raise(msg_or_exc, msg=msg_or_exc, trace=caller)
Notification.send_to(:admin, msg_or_exc) if msg_or_exc.kind_of? StandardError
fail msg_or_exc, msg=msg_or_exc, trace
end
end
module Kernel
include RaiseNotify
end
I haven't tested this, it would probably have impact beyond Rails, and I think it's a bad idea! Personally, I'd just call the notification code inside the initial rescue
clause.
def send_date
date = Date.strptime('10/100/2013', '%m/%d/%Y')
render json: {success: true, date: date}
rescue ArgumentError => e
Notification.send_to(:admin, e)
render json: {success: false, msg: 'Bad date'}
end
This may be shortened with a method:
def rescue_with_notify error_type=ArgumentError
*yield
rescue error_type => e
Notification.send_to(:admin, e)
[nil,false]
end
The idea would be to wrap what you wish to check, and respond with an array, the end of which would be the "success" flag.
def send_date date_string
date,success = rescue_with_notify do
Date.strptime(date_string, '%m/%d/%Y')
end
success = true if success.nil?
date ||= "Bad date"
render json: {success: success, date: date}
end
But this is adding complexity and maybe extra lines for very little in return. I'd stick with pasting the notification code into rescue clauses as and when it's required.