Skip to content

Instantly share code, notes, and snippets.

@Fedcomp
Last active March 30, 2017 07:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fedcomp/e8d8ac114c7013a8a7b0a3a25f60d824 to your computer and use it in GitHub Desktop.
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.
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
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