From 5313054853df0ac6fb97720c0192bb6468b0120f Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Wed, 8 Oct 2025 15:13:02 -0500 Subject: [PATCH 1/4] log sub-exceptions --- .../azure_functions_runtime/utils/tracing.py | 44 ++++--- .../v2/tests/unittests/test_threadpool.py | 4 +- runtimes/v2/tests/unittests/test_tracing.py | 111 ++++++++++++++++++ .../azure_functions_worker/utils/tracing.py | 42 +++---- workers/tests/unittests/test_tracing.py | 98 ++++++++++++++++ 5 files changed, 253 insertions(+), 46 deletions(-) create mode 100644 runtimes/v2/tests/unittests/test_tracing.py create mode 100644 workers/tests/unittests/test_tracing.py diff --git a/runtimes/v2/azure_functions_runtime/utils/tracing.py b/runtimes/v2/azure_functions_runtime/utils/tracing.py index f258ad3b6..8640dafc7 100644 --- a/runtimes/v2/azure_functions_runtime/utils/tracing.py +++ b/runtimes/v2/azure_functions_runtime/utils/tracing.py @@ -2,9 +2,6 @@ # Licensed under the MIT License. import traceback -from traceback import StackSummary, extract_tb -from typing import List - def extend_exception_message(exc: Exception, msg: str) -> Exception: # Reconstruct exception message @@ -18,26 +15,27 @@ def extend_exception_message(exc: Exception, msg: str) -> Exception: def marshall_exception_trace(exc: Exception) -> str: - stack_summary: StackSummary = extract_tb(exc.__traceback__) - if isinstance(exc, ModuleNotFoundError): - stack_summary = _marshall_module_not_found_error(stack_summary) - return ''.join(stack_summary.format()) - - -def _marshall_module_not_found_error(tbss: StackSummary) -> StackSummary: - tbss = _remove_frame_from_stack(tbss, '') - tbss = _remove_frame_from_stack( - tbss, '') - return tbss - - -def _remove_frame_from_stack(tbss: StackSummary, - framename: str) -> StackSummary: - filtered_stack_list: List[traceback.FrameSummary] = \ - list(filter(lambda frame: getattr(frame, - 'filename') != framename, tbss)) - filtered_stack: StackSummary = StackSummary.from_list(filtered_stack_list) - return filtered_stack + try: + # Use traceback.format_exception to capture the full exception chain + # This includes __cause__ and __context__ chained exceptions + full_traceback = traceback.format_exception(type(exc), exc, exc.__traceback__) + + # If it's a ModuleNotFoundError, we might want to clean up the traceback + if isinstance(exc, ModuleNotFoundError): + # For consistency with the original logic, we'll still filter + # but we need to work with the formatted strings + filtered_lines = [] + for line in full_traceback: + if '' not in line and \ + '' not in line: + filtered_lines.append(line) + return ''.join(filtered_lines) if filtered_lines else ''.join( + full_traceback) + + return ''.join(full_traceback) + except Exception as sub_exc: + return (f'Could not extract traceback. ' + f'Sub-exception: {type(sub_exc).__name__}: {str(sub_exc)}') def serialize_exception(exc: Exception, protos): diff --git a/runtimes/v2/tests/unittests/test_threadpool.py b/runtimes/v2/tests/unittests/test_threadpool.py index 59afb91b7..d4ffec730 100644 --- a/runtimes/v2/tests/unittests/test_threadpool.py +++ b/runtimes/v2/tests/unittests/test_threadpool.py @@ -1,5 +1,5 @@ -import importlib -import types +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. from azure_functions_runtime.utils import threadpool as tp diff --git a/runtimes/v2/tests/unittests/test_tracing.py b/runtimes/v2/tests/unittests/test_tracing.py new file mode 100644 index 000000000..bb4bee19a --- /dev/null +++ b/runtimes/v2/tests/unittests/test_tracing.py @@ -0,0 +1,111 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import unittest +import traceback +from azure_functions_runtime.utils.tracing import (extend_exception_message, + marshall_exception_trace, + serialize_exception, + serialize_exception_as_str) + + +class MockProtos: + class RpcException: + def __init__(self, message, stack_trace): + self.message = message + self.stack_trace = stack_trace + + +class TestExceptionUtils(unittest.TestCase): + + def test_extend_exception_message_basic(self): + exc = ValueError("Original message") + new_msg = "Extra info" + new_exc = extend_exception_message(exc, new_msg) + self.assertIsInstance(new_exc, ValueError) + self.assertIn("Original message", str(new_exc)) + self.assertIn("Extra info", str(new_exc)) + self.assertTrue(str(new_exc).endswith(new_msg)) + + def test_extend_exception_message_no_dot(self): + exc = ValueError("Message without dot") + new_exc = extend_exception_message(exc, "added") + self.assertEqual(str(new_exc), "Message without dot. added") + + def test_marshall_exception_trace_basic(self): + try: + raise ValueError("Test") + except ValueError as exc: + trace = marshall_exception_trace(exc) + self.assertIn("ValueError: Test", trace) + self.assertIn("raise ValueError", trace) + + def test_marshall_exception_trace_module_not_found(self): + try: + import non_existent_module # noqa: F401 + except ModuleNotFoundError as exc: + trace = marshall_exception_trace(exc) + self.assertIn("ModuleNotFoundError", trace) + self.assertNotIn("", trace) + + def test_marshall_exception_trace_chained_exceptions(self): + try: + try: + raise ValueError("Inner error") + except ValueError as inner: + raise RuntimeError("Outer error") from inner + except RuntimeError as exc: + trace = marshall_exception_trace(exc) + # Outer exception must appear + self.assertIn("RuntimeError: Outer error", trace) + # Inner exception must also appear + self.assertIn("ValueError: Inner error", trace) + # Ensure 'The above exception was the direct cause' appears + self.assertIn("The above exception was the direct cause", trace) + + def test_serialize_exception_returns_rpc_exception(self): + try: + raise ValueError("Error for proto") + except ValueError as exc: + result = serialize_exception(exc, MockProtos) + self.assertIsInstance(result, MockProtos.RpcException) + self.assertIn("ValueError", result.message) + self.assertIn("Error for proto", result.message) + self.assertIn("raise ValueError", result.stack_trace) + + def test_serialize_exception_as_str_basic(self): + try: + raise RuntimeError("Runtime issue") + except RuntimeError as exc: + result = serialize_exception_as_str(exc) + self.assertIn("RuntimeError: Runtime issue", result) + self.assertIn("Stack Trace:", result) + self.assertIn("raise RuntimeError", result) + + def test_serialize_exception_with_unserializable_exception(self): + class BadExc(Exception): + def __str__(self): + raise ValueError("Cannot stringify") + + exc = BadExc() + result_str = serialize_exception_as_str(exc) + self.assertIn("Could not serialize original exception message", result_str) + + result_proto = serialize_exception(exc, MockProtos) + self.assertIn("Could not serialize original exception message", + result_proto.message) + + def test_marshall_exception_trace_sub_exception(self): + # Patch traceback.format_exception to raise inside marshall_exception_trace + original_format_exception = traceback.format_exception + + def bad_format(*args, **kwargs): + raise RuntimeError("fail inside traceback") + traceback.format_exception = bad_format + try: + exc = ValueError("test") + result = marshall_exception_trace(exc) + self.assertIn("Could not extract traceback", result) + self.assertIn("RuntimeError", result) + finally: + traceback.format_exception = original_format_exception diff --git a/workers/azure_functions_worker/utils/tracing.py b/workers/azure_functions_worker/utils/tracing.py index 0e08bf84a..fbac911b3 100644 --- a/workers/azure_functions_worker/utils/tracing.py +++ b/workers/azure_functions_worker/utils/tracing.py @@ -1,8 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. import traceback -from traceback import StackSummary, extract_tb -from typing import List def extend_exception_message(exc: Exception, msg: str) -> Exception: @@ -17,23 +15,25 @@ def extend_exception_message(exc: Exception, msg: str) -> Exception: def marshall_exception_trace(exc: Exception) -> str: - stack_summary: StackSummary = extract_tb(exc.__traceback__) - if isinstance(exc, ModuleNotFoundError): - stack_summary = _marshall_module_not_found_error(stack_summary) - return ''.join(stack_summary.format()) + try: + # Use traceback.format_exception to capture the full exception chain + # This includes __cause__ and __context__ chained exceptions + full_traceback = traceback.format_exception(type(exc), exc, exc.__traceback__) + + # If it's a ModuleNotFoundError, we might want to clean up the traceback + if isinstance(exc, ModuleNotFoundError): + # For consistency with the original logic, we'll still filter + # but we need to work with the formatted strings + filtered_lines = [] + for line in full_traceback: + if '' not in line and \ + '' not in line: + filtered_lines.append(line) + return ''.join(filtered_lines) if filtered_lines else ''.join( + full_traceback) + + return ''.join(full_traceback) + except Exception as sub_exc: + return (f'Could not extract traceback. ' + f'Sub-exception: {type(sub_exc).__name__}: {str(sub_exc)}') - -def _marshall_module_not_found_error(tbss: StackSummary) -> StackSummary: - tbss = _remove_frame_from_stack(tbss, '') - tbss = _remove_frame_from_stack( - tbss, '') - return tbss - - -def _remove_frame_from_stack(tbss: StackSummary, - framename: str) -> StackSummary: - filtered_stack_list: List[traceback.FrameSummary] = \ - list(filter(lambda frame: getattr(frame, - 'filename') != framename, tbss)) - filtered_stack: StackSummary = StackSummary.from_list(filtered_stack_list) - return filtered_stack diff --git a/workers/tests/unittests/test_tracing.py b/workers/tests/unittests/test_tracing.py new file mode 100644 index 000000000..24f62dd91 --- /dev/null +++ b/workers/tests/unittests/test_tracing.py @@ -0,0 +1,98 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import unittest +import traceback +from azure_functions_worker.utils.tracing import (extend_exception_message, + marshall_exception_trace) +from azure_functions_worker.dispatcher import Dispatcher + + +class MockProtos: + class RpcException: + def __init__(self, message, stack_trace): + self.message = message + self.stack_trace = stack_trace + + +class TestExceptionUtils(unittest.TestCase): + + def test_extend_exception_message_basic(self): + exc = ValueError("Original message") + new_msg = "Extra info" + new_exc = extend_exception_message(exc, new_msg) + self.assertIsInstance(new_exc, ValueError) + self.assertIn("Original message", str(new_exc)) + self.assertIn("Extra info", str(new_exc)) + self.assertTrue(str(new_exc).endswith(new_msg)) + + def test_extend_exception_message_no_dot(self): + exc = ValueError("Message without dot") + new_exc = extend_exception_message(exc, "added") + self.assertEqual(str(new_exc), "Message without dot. added") + + def test_marshall_exception_trace_basic(self): + try: + raise ValueError("Test") + except ValueError as exc: + trace = marshall_exception_trace(exc) + self.assertIn("ValueError: Test", trace) + self.assertIn("raise ValueError", trace) + + def test_marshall_exception_trace_module_not_found(self): + try: + import non_existent_module # noqa: F401 + except ModuleNotFoundError as exc: + trace = marshall_exception_trace(exc) + self.assertIn("ModuleNotFoundError", trace) + self.assertNotIn("", trace) + + def test_marshall_exception_trace_chained_exceptions(self): + try: + try: + raise ValueError("Inner error") + except ValueError as inner: + raise RuntimeError("Outer error") from inner + except RuntimeError as exc: + trace = marshall_exception_trace(exc) + # Outer exception must appear + self.assertIn("RuntimeError: Outer error", trace) + # Inner exception must also appear + self.assertIn("ValueError: Inner error", trace) + # Ensure 'The above exception was the direct cause' appears + self.assertIn("The above exception was the direct cause", trace) + + def test_serialize_exception_returns_rpc_exception(self): + try: + raise ValueError("Error for proto") + except ValueError as exc: + result = Dispatcher._serialize_exception(exc) + self.assertIsInstance(result, MockProtos.RpcException) + self.assertIn("ValueError", result.message) + self.assertIn("Error for proto", result.message) + self.assertIn("raise ValueError", result.stack_trace) + + def test_serialize_exception_with_unserializable_exception(self): + class BadExc(Exception): + def __str__(self): + raise ValueError("Cannot stringify") + + exc = BadExc() + result_proto = Dispatcher._serialize_exception(exc) + self.assertIn("Could not serialize original exception message", + result_proto.message) + + def test_marshall_exception_trace_sub_exception(self): + # Patch traceback.format_exception to raise inside marshall_exception_trace + original_format_exception = traceback.format_exception + + def bad_format(*args, **kwargs): + raise RuntimeError("fail inside traceback") + traceback.format_exception = bad_format + try: + exc = ValueError("test") + result = marshall_exception_trace(exc) + self.assertIn("Could not extract traceback", result) + self.assertIn("RuntimeError", result) + finally: + traceback.format_exception = original_format_exception From 84a725740923c7a90f027a2c6659649210fdd0dd Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Wed, 8 Oct 2025 15:19:11 -0500 Subject: [PATCH 2/4] flake + v1 --- .../utils/tracing.py | 49 ++++---- runtimes/v1/tests/unittests/test_tracing.py | 111 ++++++++++++++++++ .../azure_functions_runtime/utils/tracing.py | 2 +- .../azure_functions_worker/utils/tracing.py | 3 +- workers/tests/unittests/test_tracing.py | 2 +- 5 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 runtimes/v1/tests/unittests/test_tracing.py diff --git a/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py b/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py index d90be0cf1..1b463fbc3 100644 --- a/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py +++ b/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py @@ -1,16 +1,12 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. - import traceback -from traceback import StackSummary, extract_tb -from typing import List - def extend_exception_message(exc: Exception, msg: str) -> Exception: # Reconstruct exception message # From: ImportModule: no module name - # To: ImportModule: no module name. msg + # To: ImportModule: no module name. msg old_tb = exc.__traceback__ old_msg = getattr(exc, 'msg', None) or str(exc) or '' new_msg = (old_msg.rstrip('.') + '. ' + msg).rstrip() @@ -19,26 +15,27 @@ def extend_exception_message(exc: Exception, msg: str) -> Exception: def marshall_exception_trace(exc: Exception) -> str: - stack_summary: StackSummary = extract_tb(exc.__traceback__) - if isinstance(exc, ModuleNotFoundError): - stack_summary = _marshall_module_not_found_error(stack_summary) - return ''.join(stack_summary.format()) - - -def _marshall_module_not_found_error(tbss: StackSummary) -> StackSummary: - tbss = _remove_frame_from_stack(tbss, '') - tbss = _remove_frame_from_stack( - tbss, '') - return tbss - - -def _remove_frame_from_stack(tbss: StackSummary, - framename: str) -> StackSummary: - filtered_stack_list: List[traceback.FrameSummary] = \ - list(filter(lambda frame: getattr(frame, - 'filename') != framename, tbss)) - filtered_stack: StackSummary = StackSummary.from_list(filtered_stack_list) - return filtered_stack + try: + # Use traceback.format_exception to capture the full exception chain + # This includes __cause__ and __context__ chained exceptions + full_traceback = traceback.format_exception(type(exc), exc, exc.__traceback__) + + # If it's a ModuleNotFoundError, we might want to clean up the traceback + if isinstance(exc, ModuleNotFoundError): + # For consistency with the original logic, we'll still filter + # but we need to work with the formatted strings + filtered_lines = [] + for line in full_traceback: + if '' not in line and \ + '' not in line: + filtered_lines.append(line) + return ''.join(filtered_lines) if filtered_lines else ''.join( + full_traceback) + + return ''.join(full_traceback) + except Exception as sub_exc: + return (f'Could not extract traceback. ' + f'Sub-exception: {type(sub_exc).__name__}: {str(sub_exc)}') def serialize_exception(exc: Exception, protos): @@ -47,10 +44,12 @@ def serialize_exception(exc: Exception, protos): except Exception: message = ('Unhandled exception in function. ' 'Could not serialize original exception message.') + try: stack_trace = marshall_exception_trace(exc) except Exception: stack_trace = '' + return protos.RpcException(message=message, stack_trace=stack_trace) diff --git a/runtimes/v1/tests/unittests/test_tracing.py b/runtimes/v1/tests/unittests/test_tracing.py new file mode 100644 index 000000000..6fd7eff5b --- /dev/null +++ b/runtimes/v1/tests/unittests/test_tracing.py @@ -0,0 +1,111 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import unittest +import traceback +from azure_functions_runtime_v1.utils.tracing import (extend_exception_message, + marshall_exception_trace, + serialize_exception, + serialize_exception_as_str) + + +class MockProtos: + class RpcException: + def __init__(self, message, stack_trace): + self.message = message + self.stack_trace = stack_trace + + +class TestExceptionUtils(unittest.TestCase): + + def test_extend_exception_message_basic(self): + exc = ValueError("Original message") + new_msg = "Extra info" + new_exc = extend_exception_message(exc, new_msg) + self.assertIsInstance(new_exc, ValueError) + self.assertIn("Original message", str(new_exc)) + self.assertIn("Extra info", str(new_exc)) + self.assertTrue(str(new_exc).endswith(new_msg)) + + def test_extend_exception_message_no_dot(self): + exc = ValueError("Message without dot") + new_exc = extend_exception_message(exc, "added") + self.assertEqual(str(new_exc), "Message without dot. added") + + def test_marshall_exception_trace_basic(self): + try: + raise ValueError("Test") + except ValueError as exc: + trace = marshall_exception_trace(exc) + self.assertIn("ValueError: Test", trace) + self.assertIn("raise ValueError", trace) + + def test_marshall_exception_trace_module_not_found(self): + try: + import non_existent_module # noqa: F401 + except ModuleNotFoundError as exc: + trace = marshall_exception_trace(exc) + self.assertIn("ModuleNotFoundError", trace) + self.assertNotIn("", trace) + + def test_marshall_exception_trace_chained_exceptions(self): + try: + try: + raise ValueError("Inner error") + except ValueError as inner: + raise RuntimeError("Outer error") from inner + except RuntimeError as exc: + trace = marshall_exception_trace(exc) + # Outer exception must appear + self.assertIn("RuntimeError: Outer error", trace) + # Inner exception must also appear + self.assertIn("ValueError: Inner error", trace) + # Ensure 'The above exception was the direct cause' appears + self.assertIn("The above exception was the direct cause", trace) + + def test_serialize_exception_returns_rpc_exception(self): + try: + raise ValueError("Error for proto") + except ValueError as exc: + result = serialize_exception(exc, MockProtos) + self.assertIsInstance(result, MockProtos.RpcException) + self.assertIn("ValueError", result.message) + self.assertIn("Error for proto", result.message) + self.assertIn("raise ValueError", result.stack_trace) + + def test_serialize_exception_as_str_basic(self): + try: + raise RuntimeError("Runtime issue") + except RuntimeError as exc: + result = serialize_exception_as_str(exc) + self.assertIn("RuntimeError: Runtime issue", result) + self.assertIn("Stack Trace:", result) + self.assertIn("raise RuntimeError", result) + + def test_serialize_exception_with_unserializable_exception(self): + class BadExc(Exception): + def __str__(self): + raise ValueError("Cannot stringify") + + exc = BadExc() + result_str = serialize_exception_as_str(exc) + self.assertIn("Could not serialize original exception message", result_str) + + result_proto = serialize_exception(exc, MockProtos) + self.assertIn("Could not serialize original exception message", + result_proto.message) + + def test_marshall_exception_trace_sub_exception(self): + # Patch traceback.format_exception to raise inside marshall_exception_trace + original_format_exception = traceback.format_exception + + def bad_format(*args, **kwargs): + raise RuntimeError("fail inside traceback") + traceback.format_exception = bad_format + try: + exc = ValueError("test") + result = marshall_exception_trace(exc) + self.assertIn("Could not extract traceback", result) + self.assertIn("RuntimeError", result) + finally: + traceback.format_exception = original_format_exception diff --git a/runtimes/v2/azure_functions_runtime/utils/tracing.py b/runtimes/v2/azure_functions_runtime/utils/tracing.py index 8640dafc7..1b463fbc3 100644 --- a/runtimes/v2/azure_functions_runtime/utils/tracing.py +++ b/runtimes/v2/azure_functions_runtime/utils/tracing.py @@ -6,7 +6,7 @@ def extend_exception_message(exc: Exception, msg: str) -> Exception: # Reconstruct exception message # From: ImportModule: no module name - # To: ImportModule: no module name. msg + # To: ImportModule: no module name. msg old_tb = exc.__traceback__ old_msg = getattr(exc, 'msg', None) or str(exc) or '' new_msg = (old_msg.rstrip('.') + '. ' + msg).rstrip() diff --git a/workers/azure_functions_worker/utils/tracing.py b/workers/azure_functions_worker/utils/tracing.py index fbac911b3..314fa142e 100644 --- a/workers/azure_functions_worker/utils/tracing.py +++ b/workers/azure_functions_worker/utils/tracing.py @@ -6,7 +6,7 @@ def extend_exception_message(exc: Exception, msg: str) -> Exception: # Reconstruct exception message # From: ImportModule: no module name - # To: ImportModule: no module name. msg + # To: ImportModule: no module name. msg old_tb = exc.__traceback__ old_msg = getattr(exc, 'msg', None) or str(exc) or '' new_msg = (old_msg.rstrip('.') + '. ' + msg).rstrip() @@ -36,4 +36,3 @@ def marshall_exception_trace(exc: Exception) -> str: except Exception as sub_exc: return (f'Could not extract traceback. ' f'Sub-exception: {type(sub_exc).__name__}: {str(sub_exc)}') - diff --git a/workers/tests/unittests/test_tracing.py b/workers/tests/unittests/test_tracing.py index 24f62dd91..52f9eb224 100644 --- a/workers/tests/unittests/test_tracing.py +++ b/workers/tests/unittests/test_tracing.py @@ -4,7 +4,7 @@ import unittest import traceback from azure_functions_worker.utils.tracing import (extend_exception_message, - marshall_exception_trace) + marshall_exception_trace) from azure_functions_worker.dispatcher import Dispatcher From 4d773108eb27c5551128052d3b4bf76af3c4cbbb Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Wed, 8 Oct 2025 16:03:59 -0500 Subject: [PATCH 3/4] fix legacy test --- workers/tests/unittests/test_tracing.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/workers/tests/unittests/test_tracing.py b/workers/tests/unittests/test_tracing.py index 52f9eb224..a1addc385 100644 --- a/workers/tests/unittests/test_tracing.py +++ b/workers/tests/unittests/test_tracing.py @@ -62,16 +62,6 @@ def test_marshall_exception_trace_chained_exceptions(self): # Ensure 'The above exception was the direct cause' appears self.assertIn("The above exception was the direct cause", trace) - def test_serialize_exception_returns_rpc_exception(self): - try: - raise ValueError("Error for proto") - except ValueError as exc: - result = Dispatcher._serialize_exception(exc) - self.assertIsInstance(result, MockProtos.RpcException) - self.assertIn("ValueError", result.message) - self.assertIn("Error for proto", result.message) - self.assertIn("raise ValueError", result.stack_trace) - def test_serialize_exception_with_unserializable_exception(self): class BadExc(Exception): def __str__(self): From 2818a2d113e8d02e9d645826f29e2f8e61a5c701 Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Thu, 9 Oct 2025 11:33:02 -0500 Subject: [PATCH 4/4] remove else statement --- runtimes/v1/azure_functions_runtime_v1/utils/tracing.py | 4 ++-- runtimes/v2/azure_functions_runtime/utils/tracing.py | 4 ++-- workers/azure_functions_worker/utils/tracing.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py b/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py index 1b463fbc3..64de249cc 100644 --- a/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py +++ b/runtimes/v1/azure_functions_runtime_v1/utils/tracing.py @@ -29,8 +29,8 @@ def marshall_exception_trace(exc: Exception) -> str: if '' not in line and \ '' not in line: filtered_lines.append(line) - return ''.join(filtered_lines) if filtered_lines else ''.join( - full_traceback) + if filtered_lines: + return ''.join(filtered_lines) return ''.join(full_traceback) except Exception as sub_exc: diff --git a/runtimes/v2/azure_functions_runtime/utils/tracing.py b/runtimes/v2/azure_functions_runtime/utils/tracing.py index 1b463fbc3..64de249cc 100644 --- a/runtimes/v2/azure_functions_runtime/utils/tracing.py +++ b/runtimes/v2/azure_functions_runtime/utils/tracing.py @@ -29,8 +29,8 @@ def marshall_exception_trace(exc: Exception) -> str: if '' not in line and \ '' not in line: filtered_lines.append(line) - return ''.join(filtered_lines) if filtered_lines else ''.join( - full_traceback) + if filtered_lines: + return ''.join(filtered_lines) return ''.join(full_traceback) except Exception as sub_exc: diff --git a/workers/azure_functions_worker/utils/tracing.py b/workers/azure_functions_worker/utils/tracing.py index 314fa142e..d79aa9d5e 100644 --- a/workers/azure_functions_worker/utils/tracing.py +++ b/workers/azure_functions_worker/utils/tracing.py @@ -29,8 +29,8 @@ def marshall_exception_trace(exc: Exception) -> str: if '' not in line and \ '' not in line: filtered_lines.append(line) - return ''.join(filtered_lines) if filtered_lines else ''.join( - full_traceback) + if filtered_lines: + return ''.join(filtered_lines) return ''.join(full_traceback) except Exception as sub_exc: