diff --git a/CHANGELOG.md b/CHANGELOG.md index 2545ea1fb..6de644314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Update key, unit and tags sanitization logic for metrics [#2292](https://github.com/getsentry/sentry-ruby/pull/2292) - Consolidate client report and rate limit handling with data categories [#2294](https://github.com/getsentry/sentry-ruby/pull/2294) +- Record `:network_error` client reports for `send_envelope` [#2295](https://github.com/getsentry/sentry-ruby/pull/2295) ### Bug Fixes diff --git a/sentry-ruby/lib/sentry/client.rb b/sentry-ruby/lib/sentry/client.rb index 5dccffdc9..608c4e1d5 100644 --- a/sentry-ruby/lib/sentry/client.rb +++ b/sentry-ruby/lib/sentry/client.rb @@ -206,9 +206,12 @@ def send_envelope(envelope) transport.send_envelope(envelope) if configuration.sending_to_dsn_allowed? spotlight_transport.send_envelope(envelope) if spotlight_transport rescue => e - # note that we don't record client reports for direct envelope types - # such as metrics, sessions etc log_error("Envelope sending failed", e, debug: configuration.debug) + + envelope.items.map(&:data_category).each do |data_category| + transport.record_lost_event(:network_error, data_category) + end + raise end diff --git a/sentry-ruby/spec/sentry/client_spec.rb b/sentry-ruby/spec/sentry/client_spec.rb index f83643ee7..bd1debcf2 100644 --- a/sentry-ruby/spec/sentry/client_spec.rb +++ b/sentry-ruby/spec/sentry/client_spec.rb @@ -98,7 +98,9 @@ def sentry_context describe '#send_envelope' do let(:envelope) do envelope = Sentry::Envelope.new({ env_header: 1 }) - envelope.add_item({ item_header: 42 }, { payload: 'test' }) + envelope.add_item({ type: 'event' }, { payload: 'test' }) + envelope.add_item({ type: 'statsd' }, { payload: 'test2' }) + envelope.add_item({ type: 'transaction' }, { payload: 'test3' }) envelope end @@ -122,18 +124,34 @@ def sentry_context subject.send_envelope(envelope) end - it 'logs error when transport failure' do - string_io = StringIO.new - configuration.debug = true - configuration.logger = ::Logger.new(string_io) - expect(subject.transport).to receive(:send_envelope).and_raise(Sentry::ExternalError.new("networking error")) + context 'when transport failure' do + let(:string_io) { StringIO.new } + + before do + configuration.debug = true + configuration.logger = ::Logger.new(string_io) + + allow(subject.transport).to receive(:send_envelope).and_raise(Sentry::ExternalError.new("networking error")) + end - expect do - subject.send_envelope(envelope) - end.to raise_error(Sentry::ExternalError) + it 'logs error' do + expect do + subject.send_envelope(envelope) + end.to raise_error(Sentry::ExternalError) - expect(string_io.string).to match(/Envelope sending failed: networking error/) - expect(string_io.string).to match(__FILE__) + expect(string_io.string).to match(/Envelope sending failed: networking error/) + expect(string_io.string).to match(__FILE__) + end + + it 'records client reports for network errors' do + expect do + subject.send_envelope(envelope) + end.to raise_error(Sentry::ExternalError) + + expect(subject.transport).to have_recorded_lost_event(:network_error, 'error') + expect(subject.transport).to have_recorded_lost_event(:network_error, 'metric_bucket') + expect(subject.transport).to have_recorded_lost_event(:network_error, 'transaction') + end end end