diff --git a/ddtrace/internal/native/_native.pyi b/ddtrace/internal/native/_native.pyi index ef03253c35c..dbe26b922de 100644 --- a/ddtrace/internal/native/_native.pyi +++ b/ddtrace/internal/native/_native.pyi @@ -712,3 +712,11 @@ class config: def set_128_bit_trace_id_enabled(val: bool) -> None: """Set whether 128-bit trace ID generation is enabled.""" ... + @staticmethod + def get_raise() -> bool: + """Return whether errors in event listeners should be re-raised (DD_TESTING_RAISE).""" + ... + @staticmethod + def set_raise(val: bool) -> None: + """Set whether errors in event listeners should be re-raised (DD_TESTING_RAISE).""" + ... diff --git a/ddtrace/internal/settings/_config.py b/ddtrace/internal/settings/_config.py index c67a75bd531..b7e77827462 100644 --- a/ddtrace/internal/settings/_config.py +++ b/ddtrace/internal/settings/_config.py @@ -633,7 +633,7 @@ def __init__(self) -> None: self._x_datadog_tags_enabled = x_datadog_tags_max_length > 0 # Raise certain errors only if in testing raise mode to prevent crashing in production with non-critical errors - self._raise = _get_config("DD_TESTING_RAISE", False, asbool) + _native_config.set_raise(_get_config("DD_TESTING_RAISE", False, asbool)) trace_compute_stats_default = in_gcp_function() or in_azure_function() or sys.version_info >= (3, 14) self._trace_compute_stats = _get_config( @@ -746,6 +746,14 @@ def __init__(self) -> None: self._report_hostname = True self._health_metrics_enabled = False + @property + def _raise(self) -> bool: + return _native_config.get_raise() + + @_raise.setter + def _raise(self, value: bool) -> None: + _native_config.set_raise(bool(value)) + @property def _128_bit_trace_id_enabled(self) -> bool: return _native_config.get_128_bit_trace_id_enabled() diff --git a/src/native/config.rs b/src/native/config.rs index a34f1394911..34a79118151 100644 --- a/src/native/config.rs +++ b/src/native/config.rs @@ -32,9 +32,37 @@ fn set_128_bit_trace_id_enabled_py(val: bool) { set_128_bit_trace_id_enabled(val); } +/// Whether errors in event listeners should be re-raised (DD_TESTING_RAISE). +/// +/// Default is `false`. Set by Python `Config.__init__` via +/// `ddtrace.internal.native.config.set_raise` at startup. +static RAISE: AtomicBool = AtomicBool::new(false); + +#[inline(always)] +pub fn get_raise() -> bool { + RAISE.load(Ordering::Relaxed) +} + +#[inline(always)] +pub fn set_raise(val: bool) { + RAISE.store(val, Ordering::Relaxed); +} + +#[pyo3::pyfunction(name = "get_raise")] +fn get_raise_py() -> bool { + get_raise() +} + +#[pyo3::pyfunction(name = "set_raise")] +fn set_raise_py(val: bool) { + set_raise(val); +} + #[pyo3::pymodule(name = "config")] pub fn config_module(m: &pyo3::Bound<'_, pyo3::types::PyModule>) -> pyo3::PyResult<()> { m.add_function(pyo3::wrap_pyfunction!(get_128_bit_trace_id_enabled_py, m)?)?; m.add_function(pyo3::wrap_pyfunction!(set_128_bit_trace_id_enabled_py, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(get_raise_py, m)?)?; + m.add_function(pyo3::wrap_pyfunction!(set_raise_py, m)?)?; Ok(()) } diff --git a/tests/tracer/test_global_config.py b/tests/tracer/test_global_config.py index 817bddba73f..b4b1410fb89 100644 --- a/tests/tracer/test_global_config.py +++ b/tests/tracer/test_global_config.py @@ -159,3 +159,19 @@ def test_dd_service_mapping(self): with override_env(dict(DD_SERVICE_MAPPING="foobar:bar,snafu:foo")): c = Config() assert c.service_mapping == {"foobar": "bar", "snafu": "foo"} + + +def test_raise_property_bridges_to_native(): + from ddtrace import config + from ddtrace.internal.native import config as native_config + + original = config._raise + try: + config._raise = True + assert native_config.get_raise() is True + assert config._raise is True + + native_config.set_raise(False) + assert config._raise is False + finally: + config._raise = original