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
3 changes: 3 additions & 0 deletions sentry-ruby/lib/sentry/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ class Error < StandardError

class ExternalError < Error
end

class SizeExceededError < ExternalError
end
end
7 changes: 6 additions & 1 deletion sentry-ruby/lib/sentry/transport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class Transport
:before_send,
:event_processor,
:insufficient_data,
:backpressure
:backpressure,
:send_error
]

include LoggingHelper
Expand Down Expand Up @@ -61,6 +62,10 @@ def send_envelope(envelope)
log_debug("[Transport] Sending envelope with items [#{serialized_items.map(&:type).join(', ')}] #{envelope.event_id} to Sentry")
send_data(data)
end
rescue Sentry::SizeExceededError
serialized_items&.each do |item|
record_lost_event(:send_error, item.data_category)
end
end

def serialize_envelope(envelope)
Expand Down
6 changes: 6 additions & 0 deletions sentry-ruby/lib/sentry/transport/http_transport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ def send_data(data)

if response.code.match?(/\A2\d{2}/)
handle_rate_limited_response(response) if has_rate_limited_header?(response)
elsif response.code == "413"
error_message = "HTTP 413: Envelope dropped due to exceeded size limit"
error_message += " (body: #{response.body})" if response.body && !response.body.empty?
log_warn(error_message)

raise Sentry::SizeExceededError, error_message
elsif response.code == "429"
log_debug("the server responded with status 429")
handle_rate_limited_response(response)
Expand Down
73 changes: 73 additions & 0 deletions sentry-ruby/spec/sentry/transport/http_transport_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,79 @@
end

describe "failed request handling" do
context "receive 413 response" do
let(:string_io) { StringIO.new }

before do
configuration.sdk_logger = Logger.new(string_io)
end

context "with response body" do
let(:fake_response) { build_fake_response("413", body: { detail: "Envelope too large" }) }

it "raises SizeExceededError with body in message" do
sentry_stub_request(fake_response)

expect { subject.send_data(data) }.to raise_error(
Sentry::SizeExceededError,
/HTTP 413: Envelope dropped due to exceeded size limit.*body:.*Envelope too large/
)
end

it "logs a warning message with body" do
sentry_stub_request(fake_response)

expect { subject.send_data(data) }.to raise_error(Sentry::SizeExceededError)
expect(string_io.string).to include("HTTP 413: Envelope dropped due to exceeded size limit")
expect(string_io.string).to include("Envelope too large")
end
end

context "with empty response body" do
let(:fake_response) do
Net::HTTPResponse.new("1.0", "413", "").tap do |response|
allow(response).to receive(:body).and_return("")
end
end

it "raises SizeExceededError without body in message" do
sentry_stub_request(fake_response)

expect { subject.send_data(data) }.to raise_error(
Sentry::SizeExceededError,
"HTTP 413: Envelope dropped due to exceeded size limit"
)
end
end

context "records client reports via send_envelope" do
let(:fake_response) { build_fake_response("413", body: { detail: "too large" }) }

it "records send_error for each item in the envelope" do
sentry_stub_request(fake_response)

configuration.send_client_reports = true
transport = Sentry::HTTPTransport.new(configuration)
envelope = transport.envelope_from_event(event)

transport.send_envelope(envelope)

# Should have recorded send_error for the event item
expect(transport.discarded_events[[:send_error, "error"]]).to eq(1)
end

it "does not raise the error to the caller" do
sentry_stub_request(fake_response)

configuration.send_client_reports = true
transport = Sentry::HTTPTransport.new(configuration)
envelope = transport.envelope_from_event(event)

expect { transport.send_envelope(envelope) }.not_to raise_error
end
end
end

context "receive 4xx responses" do
let(:fake_response) { build_fake_response("404") }

Expand Down
Loading