Skip to content

Commit 0428cb5

Browse files
committed
Unwrap ExceptionInfo and ExceptionWithTraceback
Instead of reporting the `ExceptionInfo` and `ExceptionWithTraceback` wrappers raised by Celery, report the exceptions that they wrap. This ensures that the exception in the OpenTelemetry span has a type and traceback that are meaningful and relevant to the developer.
1 parent 8cc10a0 commit 0428cb5

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- `opentelemetry-instrumentation-celery` Unwrap Celery's `ExceptionInfo` errors and report the actual exception that was raised. ([#1863](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1863))
11+
1012
### Added
1113

1214
- Make Flask request span attributes available for `start_span`.

instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ def add(x, y):
6464
from typing import Collection, Iterable
6565

6666
from celery import signals # pylint: disable=no-name-in-module
67+
from billiard.einfo import ExceptionInfo
68+
69+
try:
70+
from billiard.einfo import ExceptionWithTraceback # pylint: disable=no-name-in-module
71+
except ImportError:
72+
ExceptionWithTraceback = None
6773

6874
from opentelemetry import trace
6975
from opentelemetry.instrumentation.celery import utils
@@ -271,6 +277,21 @@ def _trace_failure(*args, **kwargs):
271277
return
272278

273279
if ex is not None:
280+
# Unwrap the actual exception wrapped by billiard's
281+
# `ExceptionInfo` and `ExceptionWithTraceback`.
282+
if (
283+
isinstance(ex, ExceptionInfo)
284+
and ex.exception is not None
285+
):
286+
ex = ex.exception
287+
288+
if (
289+
ExceptionWithTraceback is not None
290+
and isinstance(ex, ExceptionWithTraceback)
291+
and ex.exc is not None
292+
):
293+
ex = ex.exc
294+
274295
status_kwargs["description"] = str(ex)
275296
span.record_exception(ex)
276297
span.set_status(Status(**status_kwargs))

tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def fn_exception():
279279
assert len(span.events) == 1
280280
event = span.events[0]
281281
assert event.name == "exception"
282-
assert event.attributes[SpanAttributes.EXCEPTION_TYPE] == "ExceptionInfo"
282+
assert event.attributes[SpanAttributes.EXCEPTION_TYPE] == "Exception"
283283
assert SpanAttributes.EXCEPTION_MESSAGE in event.attributes
284284
assert (
285285
span.attributes.get(SpanAttributes.MESSAGING_MESSAGE_ID)

0 commit comments

Comments
 (0)