From 3b04b065fd90875a76db2be85a844be4c3f3ee42 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Thu, 18 Jun 2026 13:44:56 -0700 Subject: [PATCH 1/5] remove private import of ddtrace functionality --- datadog_lambda/wrapper.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py index d955480c..38bbf77f 100644 --- a/datadog_lambda/wrapper.py +++ b/datadog_lambda/wrapper.py @@ -9,7 +9,6 @@ from importlib import import_module from time import time_ns -from ddtrace.internal._exceptions import BlockingException from datadog_lambda.extension import should_use_extension, flush_extension from datadog_lambda.cold_start import ( set_cold_start, @@ -191,16 +190,17 @@ def __call__(self, event, context, **kwargs): if self.blocking_response: return self.blocking_response self.response = self.func(event, context, **kwargs) - except BlockingException: - self.blocking_response = get_asm_blocked_response(self.event_source) - except Exception: - from datadog_lambda.metric import submit_errors_metric + except Exception as e: + if type(e).__name__ == "BlockingException": + self.blocking_response = get_asm_blocked_response(self.event_source) + else: + from datadog_lambda.metric import submit_errors_metric - submit_errors_metric(context) + submit_errors_metric(context) - if self.span: - self.span.set_traceback() - raise + if self.span: + self.span.set_traceback() + raise finally: self._after(event, context) if self.blocking_response: From 14aba795b594f585b92bf9d97db3959be60ce012 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Thu, 18 Jun 2026 13:49:43 -0700 Subject: [PATCH 2/5] mock blocking exception --- tests/test_wrapper.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py index ba2cce5e..96ca17a1 100644 --- a/tests/test_wrapper.py +++ b/tests/test_wrapper.py @@ -724,11 +724,14 @@ def test_blocking_before(self): def test_blocking_during(self): self.mock_get_asm_blocking_response.return_value = None + class BlockingException(Exception): + pass + def lambda_handler(event, context): self.mock_get_asm_blocking_response.return_value = ( self.fake_blocking_response ) - raise wrapper.BlockingException() + raise BlockingException() lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler) From ea58e9b52f21e6a33030b309b6084b5bcaa1229a Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Thu, 18 Jun 2026 14:04:40 -0700 Subject: [PATCH 3/5] slightly more permissive name check --- datadog_lambda/wrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py index 38bbf77f..6843851b 100644 --- a/datadog_lambda/wrapper.py +++ b/datadog_lambda/wrapper.py @@ -191,7 +191,7 @@ def __call__(self, event, context, **kwargs): return self.blocking_response self.response = self.func(event, context, **kwargs) except Exception as e: - if type(e).__name__ == "BlockingException": + if "BlockingException" in type(e).__name__: self.blocking_response = get_asm_blocked_response(self.event_source) else: from datadog_lambda.metric import submit_errors_metric From 3cbd588b10c9fd30f1a5b4269128a14984e07130 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Tue, 23 Jun 2026 07:30:08 -0700 Subject: [PATCH 4/5] exception types --- datadog_lambda/wrapper.py | 62 ++++++++++++++++++++------------------- tests/test_wrapper.py | 2 +- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py index 6843851b..b7484ce3 100644 --- a/datadog_lambda/wrapper.py +++ b/datadog_lambda/wrapper.py @@ -2,52 +2,53 @@ # under the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import os import logging +import os import traceback -import ujson as json from importlib import import_module from time import time_ns -from datadog_lambda.extension import should_use_extension, flush_extension +import ujson as json + from datadog_lambda.cold_start import ( - set_cold_start, + ColdStartTracer, is_cold_start, - is_proactive_init, - is_new_sandbox, is_managed_instances_mode, - ColdStartTracer, + is_new_sandbox, + is_proactive_init, + set_cold_start, ) from datadog_lambda.config import config from datadog_lambda.constants import ( + Headers, TraceContextSource, XraySubsegment, - Headers, ) +from datadog_lambda.durable import ( + extract_durable_execution_status, + extract_durable_function_tags, +) +from datadog_lambda.extension import flush_extension, should_use_extension from datadog_lambda.module_name import modify_module_name from datadog_lambda.span_pointers import calculate_span_pointers from datadog_lambda.tag_object import tag_object from datadog_lambda.tracing import ( - extract_dd_trace_context, + InferredSpanInfo, create_dd_dummy_metadata_subsegment, + create_function_execution_span, + create_inferred_span, + extract_dd_trace_context, inject_correlation_ids, + is_authorizer_response, mark_trace_as_error_for_5xx_responses, + propagator, set_correlation_ids, set_dd_trace_py_root, - create_function_execution_span, - create_inferred_span, - InferredSpanInfo, - is_authorizer_response, tracer, - propagator, -) -from datadog_lambda.durable import ( - extract_durable_function_tags, - extract_durable_execution_status, ) from datadog_lambda.trigger import ( - extract_trigger_tags, extract_http_status_code_tag, + extract_trigger_tags, ) logger = logging.getLogger(__name__) @@ -57,13 +58,14 @@ # making changes to any ddtrace import. if config.appsec_enabled: + from ddtrace.internal.appsec.product import start + from datadog_lambda.asm import ( asm_set_context, - asm_start_response, asm_start_request, + asm_start_response, get_asm_blocked_response, ) - from ddtrace.internal.appsec.product import start start() @@ -190,17 +192,17 @@ def __call__(self, event, context, **kwargs): if self.blocking_response: return self.blocking_response self.response = self.func(event, context, **kwargs) - except Exception as e: - if "BlockingException" in type(e).__name__: - self.blocking_response = get_asm_blocked_response(self.event_source) - else: - from datadog_lambda.metric import submit_errors_metric + except Exception: + from datadog_lambda.metric import submit_errors_metric - submit_errors_metric(context) + submit_errors_metric(context) - if self.span: - self.span.set_traceback() - raise + if self.span: + self.span.set_traceback() + raise + except BaseException as e: + if "BlockingException" in type(e).__name__: + self.blocking_response = get_asm_blocked_response(self.event_source) finally: self._after(event, context) if self.blocking_response: diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py index 96ca17a1..35b5b9fa 100644 --- a/tests/test_wrapper.py +++ b/tests/test_wrapper.py @@ -724,7 +724,7 @@ def test_blocking_before(self): def test_blocking_during(self): self.mock_get_asm_blocking_response.return_value = None - class BlockingException(Exception): + class BlockingException(BaseException): pass def lambda_handler(event, context): From 0a4430d27e224951de5206d7e570bfee48bdd2e0 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Tue, 23 Jun 2026 10:51:41 -0700 Subject: [PATCH 5/5] undo --- datadog_lambda/wrapper.py | 44 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/datadog_lambda/wrapper.py b/datadog_lambda/wrapper.py index b7484ce3..73057983 100644 --- a/datadog_lambda/wrapper.py +++ b/datadog_lambda/wrapper.py @@ -2,53 +2,52 @@ # under the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. -import logging import os +import logging import traceback +import ujson as json from importlib import import_module from time import time_ns -import ujson as json - +from datadog_lambda.extension import should_use_extension, flush_extension from datadog_lambda.cold_start import ( - ColdStartTracer, + set_cold_start, is_cold_start, - is_managed_instances_mode, - is_new_sandbox, is_proactive_init, - set_cold_start, + is_new_sandbox, + is_managed_instances_mode, + ColdStartTracer, ) from datadog_lambda.config import config from datadog_lambda.constants import ( - Headers, TraceContextSource, XraySubsegment, + Headers, ) -from datadog_lambda.durable import ( - extract_durable_execution_status, - extract_durable_function_tags, -) -from datadog_lambda.extension import flush_extension, should_use_extension from datadog_lambda.module_name import modify_module_name from datadog_lambda.span_pointers import calculate_span_pointers from datadog_lambda.tag_object import tag_object from datadog_lambda.tracing import ( - InferredSpanInfo, - create_dd_dummy_metadata_subsegment, - create_function_execution_span, - create_inferred_span, extract_dd_trace_context, + create_dd_dummy_metadata_subsegment, inject_correlation_ids, - is_authorizer_response, mark_trace_as_error_for_5xx_responses, - propagator, set_correlation_ids, set_dd_trace_py_root, + create_function_execution_span, + create_inferred_span, + InferredSpanInfo, + is_authorizer_response, tracer, + propagator, +) +from datadog_lambda.durable import ( + extract_durable_function_tags, + extract_durable_execution_status, ) from datadog_lambda.trigger import ( - extract_http_status_code_tag, extract_trigger_tags, + extract_http_status_code_tag, ) logger = logging.getLogger(__name__) @@ -58,14 +57,13 @@ # making changes to any ddtrace import. if config.appsec_enabled: - from ddtrace.internal.appsec.product import start - from datadog_lambda.asm import ( asm_set_context, - asm_start_request, asm_start_response, + asm_start_request, get_asm_blocked_response, ) + from ddtrace.internal.appsec.product import start start()