Skip to content

Commit af8fcdd

Browse files
authored
Prevent Hub from having nil scope and client (#2402)
* Prevent Hub from having nil scope and client `Hub#pop_scope` currently can cause a Hub to have a nil scope and client, which would highly likely lead of errors. For example, `Hub#configuration` would simply cause `NoMethodError`. This commit prevents that from ever happening by making sure that `Hub#pop_scope` would at least leave a brand new scope and the old client on the stack.
1 parent 152eb5e commit af8fcdd

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
### 5.20.0
1+
## 5.20.0
22

33
- Add support for `$SENTRY_DEBUG` and `$SENTRY_SPOTLIGHT` ([#2374](https://github.com/getsentry/sentry-ruby/pull/2374))
44
- Support human readable intervals in `sidekiq-cron` ([#2387](https://github.com/getsentry/sentry-ruby/pull/2387))
@@ -10,6 +10,7 @@
1010
- Fix error events missing a DSC when there's an active span ([#2408](https://github.com/getsentry/sentry-ruby/pull/2408))
1111
- Verifies presence of client before adding a breadcrumb ([#2394](https://github.com/getsentry/sentry-ruby/pull/2394))
1212
- Fix `Net:HTTP` integration for non-ASCII URI's ([#2417](https://github.com/getsentry/sentry-ruby/pull/2417))
13+
- Prevent Hub from having nil scope and client ([#2402](https://github.com/getsentry/sentry-ruby/pull/2402))
1314

1415
## 5.19.0
1516

sentry-ruby/lib/sentry/hub.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,13 @@ def push_scope
7373
end
7474

7575
def pop_scope
76-
@stack.pop
76+
if @stack.size > 1
77+
@stack.pop
78+
else
79+
# We never want to enter a situation where we have no scope and no client
80+
client = current_client
81+
@stack = [Layer.new(client, Scope.new)]
82+
end
7783
end
7884

7985
def start_transaction(transaction: nil, custom_sampling_context: {}, instrumenter: :sentry, **options)

sentry-ruby/spec/sentry/hub_spec.rb

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,25 @@
519519

520520
describe "#pop_scope" do
521521
it "pops the current scope" do
522+
prev_scope = subject.current_scope
523+
subject.push_scope
524+
scope = subject.current_scope
522525
expect(subject.current_scope).to eq(scope)
523526
subject.pop_scope
524-
expect(subject.current_scope).to eq(nil)
527+
expect(subject.current_scope).to eq(prev_scope)
528+
end
529+
530+
it "doesn't pop the last layer" do
531+
expect(subject.instance_variable_get(:@stack).count).to eq(1)
532+
533+
subject.pop_scope
534+
535+
expect(subject.instance_variable_get(:@stack).count).to eq(1)
536+
537+
# It should be a completely new scope
538+
expect(subject.current_scope).not_to eq(scope)
539+
# But it should be the same client
540+
expect(subject.current_client).to eq(client)
525541
end
526542
end
527543

@@ -543,21 +559,6 @@
543559
expect(subject.current_scope).not_to eq(scope)
544560
expect(subject.current_scope.tags).to eq({ foo: "bar" })
545561
end
546-
547-
context "when the current_scope is nil" do
548-
before do
549-
subject.pop_scope
550-
expect(subject.current_scope).to eq(nil)
551-
end
552-
it "creates a new scope" do
553-
scope.set_tags({ foo: "bar" })
554-
555-
subject.push_scope
556-
557-
expect(subject.current_scope).not_to eq(scope)
558-
expect(subject.current_scope.tags).to eq({})
559-
end
560-
end
561562
end
562563

563564
describe '#configure_scope' do

0 commit comments

Comments
 (0)