Skip to content

fix(sdk): warn when both exporter and processor are passed to Traceloop.init()#4137

Merged
dvirski merged 2 commits into
mainfrom
dr/new/fix(sdk)-warn-when-both-exporter-and-processor-are-passed-to-Traceloop.init()
May 19, 2026
Merged

fix(sdk): warn when both exporter and processor are passed to Traceloop.init()#4137
dvirski merged 2 commits into
mainfrom
dr/new/fix(sdk)-warn-when-both-exporter-and-processor-are-passed-to-Traceloop.init()

Conversation

@dvirski
Copy link
Copy Markdown
Contributor

@dvirski dvirski commented May 13, 2026

Fixes #3046.
Problem: passing both exporter and processor is a mistake — the processor already wraps the exporter
internally. The exporter was silently ignored with no feedback to the user.

Fix: emit a UserWarning pointing at the caller's line. Also removes the redundant
exporter= from the exporter_with_custom_span_processor test fixture which had the same bug.

Summary by CodeRabbit

  • New Features

    • Traceloop.init now emits a UserWarning when both an exporter and a processor are supplied, clarifying the exporter will be ignored and advising wrapping the exporter with a processor instead.
  • Tests

    • Added a test confirming the warning is raised and that span export behavior follows the processor-wrapped exporter.

Review Change Stack

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 13, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 12b1f3b2-d411-41b2-a9b4-3712476f6500

📥 Commits

Reviewing files that changed from the base of the PR and between 0668e0c and ccd0832.

📒 Files selected for processing (3)
  • packages/traceloop-sdk/tests/conftest.py
  • packages/traceloop-sdk/tests/test_sdk_initialization.py
  • packages/traceloop-sdk/traceloop/sdk/__init__.py
💤 Files with no reviewable changes (1)
  • packages/traceloop-sdk/tests/conftest.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/traceloop-sdk/tests/test_sdk_initialization.py

📝 Walkthrough

Walkthrough

Emits a UserWarning when both exporter and processor are passed to Traceloop.init, adds a test verifying the warning and span behavior, and updates a fixture to pass processor=CustomSpanProcessor(exporter) instead of exporter=.

Changes

Exporter and Processor Warning

Layer / File(s) Summary
Warning implementation in Traceloop.init
packages/traceloop-sdk/traceloop/sdk/__init__.py
Added import warnings and conditional logic in Traceloop.init that emits a UserWarning when both exporter and processor are provided, indicating the exporter will be ignored.
Test for exporter and processor warning
packages/traceloop-sdk/tests/test_sdk_initialization.py
Expanded imports and added test_both_exporter_and_processor_warns which asserts a UserWarning matching exporter.*ignored, and verifies processor-wrapped exporter receives spans while a standalone exporter does not.
Fixture update to use processor pattern
packages/traceloop-sdk/tests/conftest.py
Updated exporter_with_custom_span_processor fixture to pass processor=CustomSpanProcessor(exporter) instead of supplying exporter= directly.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 I hop a warning, soft and clear,
When exporter and processor both appear.
Wrap the exporter, let spans flow true,
A gentle nudge from this rabbit to you. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding a warning when both exporter and processor are passed to Traceloop.init().
Linked Issues check ✅ Passed The PR addresses issue #3046 by implementing option (b): emitting a UserWarning when both exporter and processor are provided, preventing silent failures.
Out of Scope Changes check ✅ Passed All changes are directly related to the issue: adding the warning mechanism, updating the test fixture that exhibited the bug, and adding a test to verify the warning behavior.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dr/new/fix(sdk)-warn-when-both-exporter-and-processor-are-passed-to-Traceloop.init()

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/traceloop-sdk/tests/test_sdk_initialization.py (1)

235-237: ⚡ Quick win

Prefer a more robust pattern for instance cleanup.

The pattern if "_instance" in dir(): works but is fragile and non-idiomatic. A more explicit approach improves clarity and reliability.

♻️ Proposed refactor using try-except
-    if hasattr(TracerWrapper, "instance"):
-        _instance = TracerWrapper.instance
+    try:
+        _instance = TracerWrapper.instance
         del TracerWrapper.instance
+    except AttributeError:
+        _instance = None
 
     exporter = InMemorySpanExporter()
     processor = SimpleSpanProcessor(exporter)
@@ -245,5 +246,5 @@
             processor=processor,
         )
 
-    if "_instance" in dir():
+    if _instance is not None:
         TracerWrapper.instance = _instance

Also applies to: 248-249

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/traceloop-sdk/tests/test_sdk_initialization.py` around lines 235 -
237, Replace the fragile instance cleanup with a robust try/except/finally
pattern: use getattr(TracerWrapper, "instance", None) to grab the current
instance, then if it is not None call delattr(TracerWrapper, "instance") inside
a try block and in finally restore the saved instance with
setattr(TracerWrapper, "instance", saved) so the test cannot leak state; apply
the same change for the other cleanup at the second occurrence (lines
referencing TracerWrapper, _instance, instance).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/traceloop-sdk/tests/test_sdk_initialization.py`:
- Around line 235-237: Replace the fragile instance cleanup with a robust
try/except/finally pattern: use getattr(TracerWrapper, "instance", None) to grab
the current instance, then if it is not None call delattr(TracerWrapper,
"instance") inside a try block and in finally restore the saved instance with
setattr(TracerWrapper, "instance", saved) so the test cannot leak state; apply
the same change for the other cleanup at the second occurrence (lines
referencing TracerWrapper, _instance, instance).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3721c9b8-fc97-4609-a09c-6e92f952dffa

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3e696 and 0668e0c.

⛔ Files ignored due to path filters (1)
  • packages/traceloop-sdk/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • packages/traceloop-sdk/tests/conftest.py
  • packages/traceloop-sdk/tests/test_sdk_initialization.py
  • packages/traceloop-sdk/traceloop/sdk/__init__.py
💤 Files with no reviewable changes (1)
  • packages/traceloop-sdk/tests/conftest.py

Comment thread packages/traceloop-sdk/traceloop/sdk/__init__.py Outdated
Comment thread packages/traceloop-sdk/tests/test_sdk_initialization.py
@dvirski dvirski force-pushed the dr/new/fix(sdk)-warn-when-both-exporter-and-processor-are-passed-to-Traceloop.init() branch from 0668e0c to ccd0832 Compare May 18, 2026 18:27
@dvirski
Copy link
Copy Markdown
Contributor Author

dvirski commented May 19, 2026

@doronkopit5

Fixed both your comments (in resolved state now)

@dvirski dvirski merged commit 5a061d1 into main May 19, 2026
12 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.

🐛 Bug Report: exporter is ignored when processor is also defined in Traceloop.init()

4 participants