Skip to content

Commit 96cd40c

Browse files
committed
Add test case for child-parent exception handling
This tries to clarify the behavior that should happen when there is an exception raised in a child span which has been started with record_exception and set_status_on_exception to False.
1 parent 9d3d0f8 commit 96cd40c

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

opentelemetry-api/src/opentelemetry/trace/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,11 @@ def use_span(
588588
description=f"{type(exc).__name__}: {exc}",
589589
)
590590
)
591+
592+
# This causes parent spans to set their status to ERROR and to record
593+
# an exception as an event if a child span raises an exception even if
594+
# such child span was started with both record_exception and
595+
# set_status_on_exception attributes set to False.
591596
raise
592597

593598
finally:

opentelemetry-sdk/tests/trace/test_trace.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@
5555
get_span_with_dropped_attributes_events_links,
5656
new_tracer,
5757
)
58-
from opentelemetry.trace import Status, StatusCode
58+
from opentelemetry.trace import (
59+
Status,
60+
StatusCode,
61+
get_tracer,
62+
set_tracer_provider,
63+
)
5964

6065

6166
class TestTracer(unittest.TestCase):
@@ -1828,3 +1833,52 @@ def test_constant_default_trace_options(self):
18281833
self.assertEqual(
18291834
trace_api.DEFAULT_TRACE_OPTIONS, trace_api.TraceFlags.DEFAULT
18301835
)
1836+
1837+
1838+
class TestParentChildSpanException(unittest.TestCase):
1839+
def test_parent_child_span_exception(self):
1840+
"""
1841+
Tests that a parent span has its status set to ERROR when a child span
1842+
raises an exception even when the child span has its
1843+
``record_exception`` and ``set_status_on_exception`` attributes
1844+
set to ``False``.
1845+
"""
1846+
1847+
set_tracer_provider(TracerProvider())
1848+
tracer = get_tracer(__name__)
1849+
1850+
exception = Exception("exception")
1851+
1852+
exception_type = exception.__class__.__name__
1853+
exception_message = exception.args[0]
1854+
1855+
try:
1856+
with tracer.start_as_current_span(
1857+
"parent",
1858+
) as parent_span:
1859+
with tracer.start_as_current_span(
1860+
"child",
1861+
record_exception=False,
1862+
set_status_on_exception=False,
1863+
) as child_span:
1864+
raise exception
1865+
1866+
except Exception: # pylint: disable=broad-except
1867+
pass
1868+
1869+
self.assertTrue(child_span.status.is_ok)
1870+
self.assertIsNone(child_span.status.description)
1871+
self.assertTupleEqual(child_span.events, ())
1872+
1873+
self.assertFalse(parent_span.status.is_ok)
1874+
self.assertEqual(
1875+
parent_span.status.description,
1876+
f"{exception_type}: {exception_message}",
1877+
)
1878+
self.assertEqual(
1879+
parent_span.events[0].attributes["exception.type"], exception_type
1880+
)
1881+
self.assertEqual(
1882+
parent_span.events[0].attributes["exception.message"],
1883+
exception_message,
1884+
)

0 commit comments

Comments
 (0)