diff --git a/CHANGELOG.md b/CHANGELOG.md index 080b12bac..7ebd52b7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Default to `internal_error` error type for OpenTelemetry spans [#2473](https://github.com/getsentry/sentry-ruby/pull/2473) - Improve `before_send` and `before_send_transaction`'s return value handling ([#2504](https://github.com/getsentry/sentry-ruby/pull/2504)) +- Fix a crash when calling `Sentry.get_main_hub` in a trap context ([#2510](https://github.com/getsentry/sentry-ruby/pull/2510)) ### Internal diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index b7ecdea53..b426d61ec 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -308,6 +308,9 @@ def csp_report_uri # @return [Hub] def get_main_hub MUTEX.synchronize { @main_hub } + rescue ThreadError + # In some rare cases this may be called in a trap context so we need to handle it gracefully + @main_hub end # Takes an instance of Sentry::Breadcrumb and stores it to the current active scope. diff --git a/sentry-ruby/spec/sentry_spec.rb b/sentry-ruby/spec/sentry_spec.rb index 9a188e9f3..7fe45873c 100644 --- a/sentry-ruby/spec/sentry_spec.rb +++ b/sentry-ruby/spec/sentry_spec.rb @@ -70,6 +70,45 @@ end end end + + context "works within a trap context", when: { ruby_engine?: "ruby", ruby_version?: [:>=, "3.4"] } do + it "doesn't raise error when accessing main hub in trap context" do + read_pipe, write_pipe = IO.pipe + + pid = fork do + described_class.init do |config| + config.dsn = Sentry::TestHelper::DUMMY_DSN + end + + trap('HUP') do + hub = described_class.get_main_hub + + write_pipe.write(hub.class.to_s) + write_pipe.close + end + + Process.kill('HUP', Process.pid) + end + + write_pipe.close + + result = nil + retries = 0 + + while retries < 10 + break if Process.wait(pid) + + sleep 0.01 + + retries += 1 + end + + result = read_pipe.read + read_pipe.close + + expect(result).to eq("Sentry::Hub") + end + end end describe "#clone_hub_to_current_thread" do diff --git a/sentry-ruby/spec/spec_helper.rb b/sentry-ruby/spec/spec_helper.rb index 3821b3929..d4c1a4033 100644 --- a/sentry-ruby/spec/spec_helper.rb +++ b/sentry-ruby/spec/spec_helper.rb @@ -93,6 +93,10 @@ def self.rack_available? def self.ruby_version?(op, version) RUBY_VERSION.public_send(op, version) end + + def self.ruby_engine?(engine) + RUBY_ENGINE == engine + end end def fixtures_root