Skip to content

Commit

Permalink
Add at_exit block capturing unexpected termination (#397)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cawllec authored and kattrali committed May 18, 2018
1 parent 8bf6647 commit 042ed6f
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ Metrics/MethodLength:
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 111
Max: 125

# Offense count: 11
Metrics/PerceivedComplexity:
Expand Down
26 changes: 26 additions & 0 deletions lib/bugsnag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def configure(validate_api_key=true)
yield(configuration) if block_given?

check_key_valid if validate_api_key

register_at_exit
end

##
Expand Down Expand Up @@ -111,6 +113,30 @@ def notify(exception, auto_notify=false, &block)
end
end

##
# Registers an at_exit function to automatically catch errors on exit
def register_at_exit
return if at_exit_handler_installed?
@exit_handler_added = true
at_exit do
if $!
Bugsnag.notify($!, true) do |report|
report.severity = 'error'
report.severity_reason = {
:type => Bugsnag::Report::UNHANDLED_EXCEPTION
}
end
end
end
end

##
# Checks if an at_exit handler has been added
def at_exit_handler_installed?
@exit_handler_added ||= false
end

# Configuration getters
##
# Returns the client's Configuration object, or creates one if not yet created.
def configuration
Expand Down
17 changes: 0 additions & 17 deletions lib/bugsnag/integrations/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,6 @@ class Railtie < Rails::Railtie
load "bugsnag/tasks/bugsnag.rake"
end

# send notifications if a command fails in a 'rails runner' call
if self.respond_to? :runner
runner do
at_exit do
if $!
Bugsnag.notify($!, true) do |report|
report.severity = "error"
report.severity_reason = {
:type => Bugsnag::Report::UNHANDLED_EXCEPTION_MIDDLEWARE,
:attributes => FRAMEWORK_ATTRIBUTES
}
end
end
end
end
end

config.before_initialize do
# Configure bugsnag rails defaults
# Skipping API key validation as the key may be set later in an
Expand Down
56 changes: 56 additions & 0 deletions spec/bugsnag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,62 @@
end
end

describe "add_exit_handler" do

before do
Bugsnag.instance_variable_set(:@exit_handler_added, false)
end

it "automatically adds an exit handler" do
expect(Bugsnag).to receive(:register_at_exit)
Bugsnag.configure do |conf|
conf.api_key = "TEST KEY"
end
end

it "calls at_exit when register_at_exit is called" do
expect(Bugsnag).to receive(:at_exit)
Bugsnag.register_at_exit
end

it "doesn't call at_exit on subsequent calls" do
expect(Bugsnag).to receive(:at_exit).once
Bugsnag.register_at_exit
Bugsnag.register_at_exit
end

context 'with aliased at_exit' do
before do
module Kernel
alias_method :old_at_exit, :at_exit
def at_exit
begin
raise BugsnagTestException.new("Oh no")
rescue
yield
end
end
end
end

it "sends an exception when at_exit is called" do
report_mock = double('report')
expect(report_mock).to receive(:severity=).with('error')
expect(report_mock).to receive(:severity_reason=).with({
:type => Bugsnag::Report::UNHANDLED_EXCEPTION
})
expect(Bugsnag).to receive(:notify).with(kind_of(BugsnagTestException), true).and_yield(report_mock)
Bugsnag.register_at_exit
end

after do
module Kernel
alias_method :at_exit, :old_at_exit
end
end
end
end

describe 'loading integrations' do
before do
module Kernel
Expand Down
1 change: 1 addition & 0 deletions spec/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,5 @@ def debug(name, &block)
it "should have exit exception classes ignored by default" do
expect(subject.ignore_classes).to eq(Set.new([SystemExit, Interrupt]))
end

end

0 comments on commit 042ed6f

Please sign in to comment.