From 1beab8238b15b2377183c8ea9b74fc1a61332b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=89VEIL?= Date: Mon, 7 Aug 2023 15:17:20 +0200 Subject: [PATCH] Fix UnboundLocalError local variable 'start' referenced before assignment (#1889) Co-authored-by: Pablo Collins --- CHANGELOG.md | 5 +++ .../instrumentation/asgi/__init__.py | 2 +- .../tests/test_asgi_middleware.py | 34 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 909eea507d..6c22afff6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- `opentelemetry-instrumentation-asgi` Fix UnboundLocalError local variable 'start' referenced before assignment + ([#1889](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1889)) + ## Version 1.19.0/0.40b0 (2023-07-13) - `opentelemetry-instrumentation-asgi` Add `http.server.request.size` metric ([#1867](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1867)) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index a1fa1f8e31..c0dcd39fd2 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -538,6 +538,7 @@ async def __call__(self, scope, receive, send): receive: An awaitable callable yielding dictionaries send: An awaitable callable taking a single dictionary as argument. """ + start = default_timer() if scope["type"] not in ("http", "websocket"): return await self.app(scope, receive, send) @@ -591,7 +592,6 @@ async def __call__(self, scope, receive, send): send, duration_attrs, ) - start = default_timer() await self.app(scope, otel_receive, otel_send) finally: diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index 8ca82d0226..cb22174482 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -14,6 +14,7 @@ # pylint: disable=too-many-lines +import asyncio import sys import unittest from timeit import default_timer @@ -796,5 +797,38 @@ async def wrapped_app(scope, receive, send): ) +class TestAsgiApplicationRaisingError(AsgiTestBase): + def tearDown(self): + pass + + @mock.patch( + "opentelemetry.instrumentation.asgi.collect_custom_request_headers_attributes", + side_effect=ValueError("whatever"), + ) + def test_asgi_issue_1883( + self, mock_collect_custom_request_headers_attributes + ): + """ + Test that exception UnboundLocalError local variable 'start' referenced before assignment is not raised + See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1883 + """ + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + self.seed_app(app) + self.send_default_request() + try: + asyncio.get_event_loop().run_until_complete( + self.communicator.stop() + ) + except ValueError as exc_info: + self.assertEqual(exc_info.args[0], "whatever") + except Exception as exc_info: # pylint: disable=W0703 + self.fail( + "expecting ValueError('whatever'), received instead: " + + str(exc_info) + ) + else: + self.fail("expecting ValueError('whatever')") + + if __name__ == "__main__": unittest.main()