Skip to content

Handle backend 413 responses for span exports - #2338

Merged
alexmojaki merged 6 commits into
pydantic:mainfrom
Alphaxiaoteng:fix-1035-handle-backend-413
Aug 31, 2026
Merged

Handle backend 413 responses for span exports#2338
alexmojaki merged 6 commits into
pydantic:mainfrom
Alphaxiaoteng:fix-1035-handle-backend-413

Conversation

@Alphaxiaoteng

@Alphaxiaoteng Alphaxiaoteng commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • convert backend HTTP 413 responses into the existing BodyTooLargeError signal so multi-span payloads are retried in smaller batches
  • replace a rejected single span with a bounded diagnostic ReadableSpan instead of asserting or relying on suppressed instrumentation
  • keep the diagnostic payload small by dropping the rejected span's resource/scope and only copying bounded scalar stack metadata

Fixes #1035.

Tests

  • uv run --no-sync pytest -q tests/exporters — 21 passed
  • make lint — passed
  • make typecheck — passed
  • full local suite: 2434 passed; the remaining Docker/service-backed and aiohttp environment failures were reproduced unchanged on the base commit

AI assistance was used to develop and review this change; the diff and reported commands were manually inspected and executed.

Review in cubic

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The OTLP exporter now converts HTTP 413 responses into BodyTooLargeError. Multi-span batches continue to split recursively. Single oversized spans produce bounded diagnostic error spans with size, metadata, and schema attributes. Tests cover known and unknown size limits, HTTP 413 handling, diagnostic payloads, and preservation of other client-error behavior.

Merge Risk: 🔵 Low · up to 64a8c

When compression is enabled, oversized responses may record the uncompressed payload size instead of the bytes actually transmitted, which can make retry diagnostics or size-based handling inaccurate. The change is otherwise mergeable with explicit owner awareness or a follow-up fix.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #1035: HTTP 413 responses become BodyTooLargeError signals, multi-span batches split and retry, oversized single spans produce bounded diagnostic ReadableSpan objects, and re…
Out of Scope Changes check ✅ Passed The implementation and tests are focused on HTTP 413 handling, oversized span retries, diagnostic spans, and related validation. No unrelated code changes are evident.
Title check ✅ Passed The title clearly and concisely describes the main change: handling backend HTTP 413 responses during span exports.
Description check ✅ Passed The description directly explains the 413 handling, batch splitting, diagnostic span behavior, tests, and linked issue. It is related to the changeset.
Full details: Linked Issues check

Explanation

The changes satisfy issue #1035: HTTP 413 responses become BodyTooLargeError signals, multi-span batches split and retry, oversized single spans produce bounded diagnostic ReadableSpan objects, and reporting does not rely on suppressed instrumentation.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

@Alphaxiaoteng

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

CodeRabbit chat interactions are restricted to organization members for this repository. Ask an organization member to interact with CodeRabbit, or set chat.allow_non_org_members: true in your configuration.

cubic-dev-ai[bot]

This comment was marked as resolved.

@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@alexmojaki

Copy link
Copy Markdown
Contributor

Thanks!

@alexmojaki
alexmojaki enabled auto-merge August 31, 2026 13:17

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Confidence score: 4/5

  • In tests/exporters/test_retry_fewer_spans.py, removing the exception-injection regression test reduces coverage for the diagnostic re-export suppression path; a future change could leak the underlying exception instead of returning SpanExportResult.FAILURE without being detected—restore or replace the test.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/exporters/test_retry_fewer_spans.py">

<violation number="1">
P2: This removes the exception-injection regression test that verified a failure during the diagnostic re-export returns SpanExportResult.FAILURE instead of leaking the underlying exception. That suppression path is still live in otlp.py ('with handle_internal_errors' around 'super().export([error_span])'), and no other test covers it, so the previously-fixed RuntimeError leak can regress undetected. Keep a test that raises in the diagnostic export (first call BodyTooLargeError, second Raise RuntimeError) and asserts FAILURE after exactly two export attempts.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

@@ -1,8 +1,10 @@
from __future__ import annotations

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This removes the exception-injection regression test that verified a failure during the diagnostic re-export returns SpanExportResult.FAILURE instead of leaking the underlying exception. That suppression path is still live in otlp.py ('with handle_internal_errors' around 'super().export([error_span])'), and no other test covers it, so the previously-fixed RuntimeError leak can regress undetected. Keep a test that raises in the diagnostic export (first call BodyTooLargeError, second Raise RuntimeError) and asserts FAILURE after exactly two export attempts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/exporters/test_retry_fewer_spans.py, line 165:

<comment>This removes the exception-injection regression test that verified a failure during the diagnostic re-export returns SpanExportResult.FAILURE instead of leaking the underlying exception. That suppression path is still live in otlp.py ('with handle_internal_errors' around 'super().export([error_span])'), and no other test covers it, so the previously-fixed RuntimeError leak can regress undetected. Keep a test that raises in the diagnostic export (first call BodyTooLargeError, second Raise RuntimeError) and asserts FAILURE after exactly two export attempts.</comment>

<file context>
@@ -1,10 +1,10 @@
 from __future__ import annotations
 
-import json
 from collections.abc import Sequence
 from typing import cast
 
 import pytest
+from inline_snapshot import snapshot
 from opentelemetry.sdk.resources import Resource
</file context>

@alexmojaki
alexmojaki added this pull request to the merge queue Aug 31, 2026
Merged via the queue into pydantic:main with commit d08f3a7 Aug 31, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle 413 from backend better

2 participants