Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

- Include otel as custom sampling context ([2683](https://github.com/getsentry/sentry-ruby/pull/2683))

### Fixes

- Prevent logging from crashing main thread ([2795](https://github.com/getsentry/sentry-ruby/pull/2795))

## 6.1.2

### Fixes
Expand Down
9 changes: 8 additions & 1 deletion sentry-ruby/lib/sentry/log_event_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,18 @@ def size
@pending_events.size
end

def clear!
@pending_events.clear
end

private

def send_events
@client.send_logs(@pending_events)
@pending_events.clear
rescue => e
log_debug("[LogEventBuffer] Failed to send logs: #{e.message}")
ensure
clear!
end
end
end
57 changes: 57 additions & 0 deletions sentry-ruby/spec/sentry/log_event_buffer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,61 @@
expect(log_event_buffer).to be_empty
end
end

describe "error handling" do
let(:max_log_events) { 3 }

let(:error) { Errno::ECONNREFUSED.new("Connection refused") }

context "when send_logs raises an exception" do
before do
allow(client).to receive(:send_logs).and_raise(error)
end

it "does not propagate exception from add_event when buffer is full" do
expect {
3.times { log_event_buffer.add_event(log_event) }
}.not_to raise_error
end

it "does not propagate exception from flush" do
2.times { log_event_buffer.add_event(log_event) }

expect {
log_event_buffer.flush
}.not_to raise_error
end

it "logs the error to sdk_logger" do
3.times { log_event_buffer.add_event(log_event) }

expect(string_io.string).to include("Failed to send logs")
end

it "clears the buffer after a failed send to avoid memory buildup" do
3.times { log_event_buffer.add_event(log_event) }

expect(log_event_buffer).to be_empty
end
end

context "when background thread encounters an error" do
let(:max_log_events) { 100 }

before do
allow(client).to receive(:send_logs).and_raise(error)
end

it "keeps the background thread alive after an error" do
log_event_buffer.add_event(log_event)
log_event_buffer.start

thread = log_event_buffer.instance_variable_get(:@thread)

expect(thread).to be_alive
expect { log_event_buffer.flush }.not_to raise_error
expect(thread).to be_alive
end
end
end
end
Loading