`SpanProcessor.on_end` exceptions escape cleanup and replace application exceptions

Open Beginner friendly
#5,624 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
observability

Research direction

Start in opentelemetry-sdk/src/opentelemetry/sdk/trace/init.py at SynchronousMultiSpanProcessor.on_end and trace the call through Span.end. Verify that exceptions from SpanProcessor.on_end are handled and logged without replacing an application exception or escaping when no application exception exists.

Written by the indexing model from the issue text.

Description

bug
Steps to Reproduce
from opentelemetry.sdk.trace import SpanProcessor, TracerProvider

class RaisingProcessor(SpanProcessor):
    def on_end(self, span):
        raise RuntimeError("processor failed")

provider = TracerProvider()
provider.add_span_processor(RaisingProcessor())
tracer = provider.get_tracer("reproduction")

with tracer.start_as_current_span("operation"):
    raise ValueError("application failed")
Expected Result

OnEnd(Span):

This method MUST be called synchronously within the Span.End() API, therefore it should not block or throw an exception.

Error handling:

OpenTelemetry implementations MUST NOT throw unhandled exceptions at runtime.

API methods that accept external callbacks MUST handle all errors.

SynchronousMultiSpanProcessor.on_end invokes processors without an exception guard. The exception escapes through Span.end during context-manager cleanup.

Actual Result

The caller receives RuntimeError("processor failed"), with the application’s ValueError in __context__. Replacing the application’s raise with pass also propagates RuntimeError.

Would you like to implement a fix?
--- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
+++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
@@ -187,3 +187,6 @@
     def on_end(self, span: "ReadableSpan") -> None:
         for sp in self._span_processors:
-            sp.on_end(span)
+            try:
+                sp.on_end(span)
+            except Exception:
+                logger.exception("Exception while calling SpanProcessor.on_end.")
Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
5d 29m
Merged PRs (30d)
17

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from open-telemetry/opentelemetry-python

All issues in open-telemetry/opentelemetry-python

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.