Skip to content

Commit 315310f

Browse files
st0012solnic
andauthored
Improve before_send and before_send_transaction's return value handling (#2504)
* Require testing support files explicitly instead of Dir.glob - It's usually better to require files explicitly when the number of files is manageable. Given that we only need 2 at the moment, I don't think it's worth using Dir.glob. - Also, using Dir.glob causes it to load the Rakefile, which is for isolated testing and it actually initializes the SDK with the wrong configuration in other tests. * Warn when before_send and before_send_transaction callbacks return non-events Currently, if the callbacks return non-event and non-nil values, they'd cause exceptions during serialization, which are rescued and ignored, without explicit logging. This commit adds additional checks to the return values so the users get warnings and also avoids the unnecessary exceptions. * Update changelog * Update sentry-ruby/lib/sentry/client.rb Co-authored-by: Peter Solnica <[email protected]> --------- Co-authored-by: Peter Solnica <[email protected]>
1 parent a9301f3 commit 315310f

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
### Bug fixes
1010

1111
- Default to `internal_error` error type for OpenTelemetry spans [#2473](https://github.com/getsentry/sentry-ruby/pull/2473)
12+
- Improve `before_send` and `before_send_transaction`'s return value handling ([#2504](https://github.com/getsentry/sentry-ruby/pull/2504))
1213

1314
### Internal
1415

sentry-ruby/lib/sentry/client.rb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,11 @@ def send_event(event, hint = nil)
183183
if event_type != TransactionEvent::TYPE && configuration.before_send
184184
event = configuration.before_send.call(event, hint)
185185

186-
if event.nil?
187-
log_debug("Discarded event because before_send returned nil")
186+
unless event.is_a?(ErrorEvent)
187+
# Avoid serializing the event object in this case because we aren't sure what it is and what it contains
188+
log_debug(<<~MSG)
189+
Discarded event because before_send didn't return a Sentry::ErrorEvent object but an instance of #{event.class}
190+
MSG
188191
transport.record_lost_event(:before_send, data_category)
189192
return
190193
end
@@ -193,15 +196,18 @@ def send_event(event, hint = nil)
193196
if event_type == TransactionEvent::TYPE && configuration.before_send_transaction
194197
event = configuration.before_send_transaction.call(event, hint)
195198

196-
if event.nil?
197-
log_debug("Discarded event because before_send_transaction returned nil")
198-
transport.record_lost_event(:before_send, "transaction")
199-
transport.record_lost_event(:before_send, "span", num: spans_before + 1)
200-
return
201-
else
199+
if event.is_a?(TransactionEvent)
202200
spans_after = event.is_a?(TransactionEvent) ? event.spans.size : 0
203201
spans_delta = spans_before - spans_after
204202
transport.record_lost_event(:before_send, "span", num: spans_delta) if spans_delta > 0
203+
else
204+
# Avoid serializing the event object in this case because we aren't sure what it is and what it contains
205+
log_debug(<<~MSG)
206+
Discarded event because before_send_transaction didn't return a Sentry::TransactionEvent object but an instance of #{event.class}
207+
MSG
208+
transport.record_lost_event(:before_send, "transaction")
209+
transport.record_lost_event(:before_send, "span", num: spans_before + 1)
210+
return
205211
end
206212
end
207213

sentry-ruby/spec/sentry/client/event_sending_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,30 @@
248248
expect(dbl).not_to receive(:call)
249249
client.send_event(event)
250250
end
251+
252+
it "warns if before_send returns nil" do
253+
string_io = StringIO.new
254+
logger = Logger.new(string_io, level: :debug)
255+
configuration.logger = logger
256+
configuration.before_send = lambda do |_event, _hint|
257+
nil
258+
end
259+
260+
client.send_event(event)
261+
expect(string_io.string).to include("Discarded event because before_send didn't return a Sentry::ErrorEvent object but an instance of NilClass")
262+
end
263+
264+
it "warns if before_send returns non-Event objects" do
265+
string_io = StringIO.new
266+
logger = Logger.new(string_io, level: :debug)
267+
configuration.logger = logger
268+
configuration.before_send = lambda do |_event, _hint|
269+
123
270+
end
271+
272+
client.send_event(event)
273+
expect(string_io.string).to include("Discarded event because before_send didn't return a Sentry::ErrorEvent object but an instance of Integer")
274+
end
251275
end
252276

253277
it_behaves_like "Event in send_event" do
@@ -290,6 +314,18 @@
290314
expect(event["tags"]["called"]).to eq(true)
291315
end
292316
end
317+
318+
it "warns if before_send_transaction returns nil" do
319+
string_io = StringIO.new
320+
logger = Logger.new(string_io, level: :debug)
321+
configuration.logger = logger
322+
configuration.before_send_transaction = lambda do |_event, _hint|
323+
nil
324+
end
325+
326+
client.send_event(event)
327+
expect(string_io.string).to include("Discarded event because before_send_transaction didn't return a Sentry::TransactionEvent object but an instance of NilClass")
328+
end
293329
end
294330

295331
it_behaves_like "TransactionEvent in send_event" do

sentry-ruby/spec/spec_helper.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
require "sentry-ruby"
2727
require "sentry/test_helper"
2828

29-
Dir[Pathname(__dir__).join("support/**/*.rb")].sort.each { |f| require f }
29+
require "support/profiler"
30+
require "support/stacktrace_test_fixture"
3031

3132
RSpec.configure do |config|
3233
# Enable flags like --only-failures and --next-failure

0 commit comments

Comments
 (0)