Skip to content

Commit 5fce129

Browse files
committed
Prevent crashes from get_main_hub when in trap context
1 parent 3d7c0d1 commit 5fce129

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

sentry-ruby/lib/sentry-ruby.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ def csp_report_uri
308308
# @return [Hub]
309309
def get_main_hub
310310
MUTEX.synchronize { @main_hub }
311+
rescue ThreadError
312+
# In some rare cases this may be called in a trap context so we need to handle it gracefully
313+
@main_hub
311314
end
312315

313316
# Takes an instance of Sentry::Breadcrumb and stores it to the current active scope.

sentry-ruby/spec/sentry_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,46 @@
7070
end
7171
end
7272
end
73+
74+
context "works within a trap context", when: { ruby_engine?: "ruby", ruby_version?: [:>=, "3.4"] } do
75+
it "doesn't raise error when accessing main hub in trap context" do
76+
read_pipe, write_pipe = IO.pipe
77+
78+
pid = fork do
79+
read_pipe.close
80+
81+
described_class.init do |config|
82+
config.dsn = Sentry::TestHelper::DUMMY_DSN
83+
end
84+
85+
trap('HUP') do
86+
hub = described_class.get_main_hub
87+
write_pipe.write(hub.class.to_s)
88+
write_pipe.close
89+
end
90+
91+
Process.kill('HUP', Process.pid)
92+
end
93+
94+
write_pipe.close
95+
96+
result = nil
97+
retries = 0
98+
99+
while retries < 10
100+
break if Process.wait(pid)
101+
102+
sleep 0.01
103+
104+
retries += 1
105+
end
106+
107+
result = read_pipe.read unless read_pipe.closed?
108+
read_pipe.close
109+
110+
expect(result).to eq("Sentry::Hub")
111+
end
112+
end
73113
end
74114

75115
describe "#clone_hub_to_current_thread" do

sentry-ruby/spec/spec_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ def self.rack_available?
9393
def self.ruby_version?(op, version)
9494
RUBY_VERSION.public_send(op, version)
9595
end
96+
97+
def self.ruby_engine?(engine)
98+
RUBY_ENGINE == engine
99+
end
96100
end
97101

98102
def fixtures_root

0 commit comments

Comments
 (0)