From 7db672a52cdb0fd4c63a159f4ac0244f73f3ba16 Mon Sep 17 00:00:00 2001 From: saartochner Date: Mon, 4 Jan 2021 18:11:42 +0200 Subject: [PATCH 1/2] mimic boostrap.py import strategy of the original handler --- src/lumigo_tracer/auto_instrument_handler.py | 30 +++++++---- src/test/unit/test_auto_instrument_handler.py | 54 +++++++++++++++---- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/lumigo_tracer/auto_instrument_handler.py b/src/lumigo_tracer/auto_instrument_handler.py index db2707cb..c4f9d870 100644 --- a/src/lumigo_tracer/auto_instrument_handler.py +++ b/src/lumigo_tracer/auto_instrument_handler.py @@ -10,13 +10,13 @@ def parse_handler(): try: module_name, unit_name = os.environ[ORIGINAL_HANDLER_KEY].rsplit(".", 1) except KeyError: - raise ValueError( + raise Exception( "Could not find the original handler. Please contact Lumigo for more information." - ) - except ValueError: - raise RuntimeError( - f"Invalid handler format: Bad handler '{os.environ[ORIGINAL_HANDLER_KEY]}': not enough values to unpack (expected 2, got 1)" - ) + ) from None + except ValueError as e: + raise ValueError( + f"Runtime.MalformedHandlerName: Bad handler '{os.environ[ORIGINAL_HANDLER_KEY]}': {str(e)}" + ) from None importable_name = module_name.replace("/", ".") return importable_name, unit_name @@ -26,11 +26,21 @@ def _handler(*args, **kwargs): handler_module = "" try: handler_module, unit_name = parse_handler() - original_handler = getattr(importlib.import_module(handler_module), unit_name) - except (ImportError, AttributeError): + original_module = importlib.import_module(handler_module) + except ImportError as e: raise ImportError( - f"Unable to import module '{handler_module}': No module named '{handler_module}'" - ) + f"Runtime.ImportModuleError: Unable to import module '{handler_module}': {str(e)}" + ) from None + except SyntaxError as e: + raise SyntaxError( + f"Runtime.UserCodeSyntaxError: Syntax error in module '{handler_module}': {str(e)}" + ) from None + try: + original_handler = getattr(original_module, unit_name) + except AttributeError: + raise Exception( + f"Runtime.HandlerNotFound: Handler '{unit_name}' missing on module '{handler_module}'" + ) from None return original_handler(*args, **kwargs) diff --git a/src/test/unit/test_auto_instrument_handler.py b/src/test/unit/test_auto_instrument_handler.py index c606f9c9..bf7ecef3 100644 --- a/src/test/unit/test_auto_instrument_handler.py +++ b/src/test/unit/test_auto_instrument_handler.py @@ -32,33 +32,67 @@ def test_hierarchy_happy_flow(monkeypatch): def test_import_error(monkeypatch): monkeypatch.setenv(ORIGINAL_HANDLER_KEY, "blabla.not.exists") - with pytest.raises(ImportError): + try: _handler({}, {}) + except ImportError as e: + assert "Runtime.ImportModuleError" in str(e) + assert "another exception occurred" not in traceback.format_exc() + else: + assert False def test_no_env_handler_error(monkeypatch): - if os.environ.get(ORIGINAL_HANDLER_KEY): - monkeypatch.delenv(ORIGINAL_HANDLER_KEY) + monkeypatch.delenv(ORIGINAL_HANDLER_KEY, None) - with pytest.raises(ValueError): + with pytest.raises(Exception) as e: _handler({}, {}) + assert "Could not find the original handler" in str(e.value) def test_error_in_original_handler_no_extra_exception_log(monkeypatch, context): - monkeypatch.setattr(importlib, "import_module", mock.Mock(side_effect=Exception)) + monkeypatch.setattr(importlib, "import_module", mock.Mock(side_effect=ZeroDivisionError)) + monkeypatch.setenv(ORIGINAL_HANDLER_KEY, "sys.exit") + + try: + _handler({}, context) + except ZeroDivisionError: + assert "another exception occurred" not in traceback.format_exc() + else: + assert False + + +def test_error_in_original_handler_syntax_error(monkeypatch, context): + monkeypatch.setattr(importlib, "import_module", mock.Mock(side_effect=SyntaxError)) monkeypatch.setenv(ORIGINAL_HANDLER_KEY, "sys.exit") - exception_occurred = False try: _handler({}, context) - except Exception: - exception_occurred = True + except SyntaxError as e: + assert "Runtime.UserCodeSyntaxError" in str(e) assert "another exception occurred" not in traceback.format_exc() - assert exception_occurred is True + else: + assert False def test_handler_bad_format(monkeypatch): monkeypatch.setenv(ORIGINAL_HANDLER_KEY, "no_method") - with pytest.raises(RuntimeError): + try: + _handler({}, {}) + except ValueError as e: + assert "Runtime.MalformedHandlerName" in str(e) + assert "another exception occurred" not in traceback.format_exc() + else: + assert False + + +def test_handler_not_found(monkeypatch): + monkeypatch.setenv(ORIGINAL_HANDLER_KEY, "sys.not_found") + + try: _handler({}, {}) + except Exception as e: + assert "Runtime.HandlerNotFound" in str(e) + assert "another exception occurred" not in traceback.format_exc() + else: + assert False From e24d3c125a27b57dae7b42115cbe7499d7b8e667 Mon Sep 17 00:00:00 2001 From: saartochner Date: Tue, 5 Jan 2021 10:46:42 +0200 Subject: [PATCH 2/2] fix Nirhod's CR --- src/test/unit/test_auto_instrument_handler.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/unit/test_auto_instrument_handler.py b/src/test/unit/test_auto_instrument_handler.py index bf7ecef3..d269a175 100644 --- a/src/test/unit/test_auto_instrument_handler.py +++ b/src/test/unit/test_auto_instrument_handler.py @@ -35,6 +35,7 @@ def test_import_error(monkeypatch): try: _handler({}, {}) except ImportError as e: + # Note: We're not using pytest.raises in order to get the exception context assert "Runtime.ImportModuleError" in str(e) assert "another exception occurred" not in traceback.format_exc() else: @@ -56,6 +57,7 @@ def test_error_in_original_handler_no_extra_exception_log(monkeypatch, context): try: _handler({}, context) except ZeroDivisionError: + # Note: We're not using pytest.raises in order to get the exception context assert "another exception occurred" not in traceback.format_exc() else: assert False @@ -68,6 +70,7 @@ def test_error_in_original_handler_syntax_error(monkeypatch, context): try: _handler({}, context) except SyntaxError as e: + # Note: We're not using pytest.raises in order to get the exception context assert "Runtime.UserCodeSyntaxError" in str(e) assert "another exception occurred" not in traceback.format_exc() else: @@ -80,6 +83,7 @@ def test_handler_bad_format(monkeypatch): try: _handler({}, {}) except ValueError as e: + # Note: We're not using pytest.raises in order to get the exception context assert "Runtime.MalformedHandlerName" in str(e) assert "another exception occurred" not in traceback.format_exc() else: @@ -92,6 +96,7 @@ def test_handler_not_found(monkeypatch): try: _handler({}, {}) except Exception as e: + # Note: We're not using pytest.raises in order to get the exception context assert "Runtime.HandlerNotFound" in str(e) assert "another exception occurred" not in traceback.format_exc() else: