Skip to content

Commit 0d42476

Browse files
feat(transport): Report 413 responses for oversized envelopes (#5380)
Handle 413 responses in the transport. Log an error message and record a client report with the reason `send_error` when downstream envelope size limits are exceeded.
1 parent 0c81d3a commit 0d42476

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

sentry_sdk/transport.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,21 @@ def record_loss(reason: str) -> None:
340340
try:
341341
self._update_rate_limits(response)
342342

343-
if response.status == 429:
343+
if response.status == 413:
344+
size_exceeded_message = (
345+
"HTTP 413: Event dropped due to exceeded envelope size limit"
346+
)
347+
response_message = getattr(
348+
response, "data", getattr(response, "content", None)
349+
)
350+
if response_message is not None:
351+
size_exceeded_message += f" (body: {response_message})"
352+
353+
logger.error(size_exceeded_message)
354+
self.on_dropped_event("status_413")
355+
record_loss("send_error")
356+
357+
elif response.status == 429:
344358
# if we hit a 429. Something was rate limited but we already
345359
# acted on this in `self._update_rate_limits`. Note that we
346360
# do not want to record event loss here as we will have recorded

tests/test_transport.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,33 @@ def test_parse_rate_limits(input, expected):
385385
assert dict(_parse_rate_limits(input, now=NOW)) == expected
386386

387387

388+
def test_envelope_too_large_response(capturing_server, make_client):
389+
client = make_client()
390+
391+
capturing_server.respond_with(code=413)
392+
client.capture_event({"type": "error"})
393+
client.capture_event({"type": "transaction"})
394+
client.flush()
395+
396+
# Error, transaction, and client report payloads
397+
assert len(capturing_server.captured) == 3
398+
report = parse_json(capturing_server.captured[2].envelope.items[0].get_bytes())
399+
400+
# Client reports for error, transaction and included span
401+
assert len(report["discarded_events"]) == 3
402+
assert {"reason": "send_error", "category": "error", "quantity": 1} in report[
403+
"discarded_events"
404+
]
405+
assert {"reason": "send_error", "category": "span", "quantity": 1} in report[
406+
"discarded_events"
407+
]
408+
assert {"reason": "send_error", "category": "transaction", "quantity": 1} in report[
409+
"discarded_events"
410+
]
411+
412+
capturing_server.clear_captured()
413+
414+
388415
def test_simple_rate_limits(capturing_server, make_client):
389416
client = make_client()
390417
capturing_server.respond_with(code=429, headers={"Retry-After": "4"})

0 commit comments

Comments
 (0)