Last active
March 30, 2017 07:14
-
-
Save Fedcomp/e8d8ac114c7013a8a7b0a3a25f60d824 to your computer and use it in GitHub Desktop.
Ruby exception handler that uses exception notifier to send exception notification and silently handles exception on production.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'exception_notification/rails' | |
# Capture errors in production and return nil | |
module Failsafe | |
def failsafe(&_block) | |
yield | |
rescue => e | |
# Show errors only during development | |
if Rails.env.test? || Rails.env.development? | |
raise e | |
else | |
# On production environments handle the error | |
# but send email to developers with exception | |
# ExceptionNotifier.notify_exception( | |
# exception, env: request.env, | |
# data: { message: 'Failsafe handled exception' } | |
# ) | |
::ExceptionNotifier.notify_exception(e, failsafe_params) | |
nil | |
end | |
end | |
# Allow classes to redefine method | |
# this way you can send additional data in email | |
def failsafe_params; end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
class FailsafeTestClass | |
include Failsafe | |
def unsafe_action | |
failsafe { name } | |
end | |
def safe_action | |
failsafe { 'success' } | |
end | |
private | |
def name | |
crashme | |
end | |
# Should be called and result sent in email | |
def failsafe_params | |
{ data: 'some' } | |
end | |
end | |
RSpec.describe Failsafe, type: :service do | |
describe '.failsafe' do | |
subject { FailsafeTestClass.new } | |
it 'should fail silently on production' do | |
expect(Rails.env).to receive(:test?).and_return(false) | |
expect { subject.unsafe_action }.to_not raise_error | |
end | |
it 'should send email on production' do | |
expect(Rails.env).to receive(:test?).and_return(false) | |
expect(ExceptionNotifier).to receive(:notify_exception) | |
.with(instance_of(NameError), hash_including(data: 'some')) | |
subject.unsafe_action | |
end | |
it 'should explicitly fail during development' do | |
expect { subject.unsafe_action }.to raise_error(NameError) | |
end | |
it 'should return value in case of no failure' do | |
expect(subject.safe_action).to eq 'success' | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment