Skip to content

feat(span-first): Support before_send_span#6239

Draft
sentrivana wants to merge 9 commits intomasterfrom
ivana/span-first-before-send-span
Draft

feat(span-first): Support before_send_span#6239
sentrivana wants to merge 9 commits intomasterfrom
ivana/span-first-before-send-span

Conversation

@sentrivana
Copy link
Copy Markdown
Contributor

@sentrivana sentrivana commented May 8, 2026

Description

Add support for before_send_span in span streaming mode.

before_send_span is different from before_send_metric and before_send_log in that:

  • it doesn't allow users to drop a span (i.e., return None)
  • it only allows to modify specific parts of the span (name and attributes)

To that end, we're exposing a copy of the span in the callback instead of the real thing. Alternatively, we could just expose a simplified dictionary snapshot of the span ({"name": "name", "attributes": {}}), but that'd then bypass any extra logic we have in the span public API (like set_attribute(), which currently stringifies values if not serializable).

See https://develop.sentry.dev/sdk/telemetry/spans/scrubbing-data/ for spec.

TODO

  • Looks like we have some unserializable stuff on spans. Need to figure out what it is and why it's there. If we can't get rid of it it might need a stripped down version of the span or a snapshot after all

Issues

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 8, 2026

PY-2057

@sentrivana sentrivana changed the title feat(span-first): Support before_send_span feat(span-first): Support before_send_span May 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

Codecov Results 📊

13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 8.13s

All tests are passing successfully.

❌ Patch coverage is 45.00%. Project has 15112 uncovered lines.

Files with missing lines (3)
File Patch % Lines
utils.py 54.05% ⚠️ 431 Missing and 88 partials
client.py 59.45% ⚠️ 223 Missing and 69 partials
consts.py 99.48% ⚠️ 2 Missing

Generated by Codecov Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

Codecov Results 📊

44 passed | ❌ 13 failed | Total: 57 | Pass Rate: 77.19% | Execution Time: 9.62s

❌ Failed Tests

test_tracing_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:42227/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1159: in test_tracing_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:42227/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_sensitive_header_scrubbing_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:43849/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1227: in test_sensitive_header_scrubbing_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:43849/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_sensitive_header_passthrough_with_pii_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: ValueError: not enough values to unpack (expected 1, got 0)

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1273: in test_sensitive_header_passthrough_with_pii_span_streaming
    (server_span,) = [item.payload for item in items]
E   ValueError: not enough values to unpack (expected 1, got 0)

test_request_body_captured_on_segment_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:37321/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1311: in test_request_body_captured_on_segment_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:37321/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_request_body_not_read_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:45665/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1341: in test_request_body_not_read_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:45665/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:13 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_request_body_over_size_limit_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:44169/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1375: in test_request_body_over_size_limit_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:44169/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_url_query_attribute_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:44099/?foo=bar&baz=qux) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1407: in test_url_query_attribute_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:44099/?foo=bar&baz=qux) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_transaction_style_span_streaming[pyloop-/message-handler_name-tests.integrations.aiohttp.test_aiohttp.test_transaction_style_span_streaming.<locals>.hello-component]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:42867/message) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1461: in test_transaction_style_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:42867/message) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_transaction_style_span_streaming[pyloop-/message-method_and_path_pattern-GET /{var}-route]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 200 + where 500 = <ClientResponse(http://127.0.0.1:36003/message) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1461: in test_transaction_style_span_streaming
    assert resp.status == 200
E   AssertionError: assert 500 == 200
E    +  where 500 = <ClientResponse(http://127.0.0.1:36003/message) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:14 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_server_error_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: assert 2 == 3 + where 2 = len([UnwrappedItem(type='event', payload={'level': 'error', 'exception': {'values': [{'mechanism': {'type': 'aiohttp', 'handled': False}, 'module': None, 'type': 'ZeroDivisionError', 'value': 'division by zero', 'stacktrace': {'frames': [{'filename': 'aiohttp/web_app.py', 'abs_path': '/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/aiohttp/web_app.py', 'function': '_handle', 'module': 'aiohttp.web_app', 'lineno': 499, 'pre_context': [' partial(m, handler=handler), handler', ' )', ' else:', ' handler = await m(app, handler) # type: ignore', ''], 'context_line': ' resp = await handler(request)', 'post_context': ['', ' return resp', '', ' def call(self) -> "Application":', ' """gunicorn compatibility"""'], 'vars': {'self': {}, 'request': {}, 'loop': '<_UnixSelectorEventLoop running=True closed=False debug=False>', 'debug': 'False', 'match_info': {}, 'resp': 'None', 'expect': 'None', 'handler': '<function test_server_error_span_streaming..hello at 0x7f1991790430>'}, 'in_app': False}, {'filename': 'tests/integrations/aiohttp/test_aiohttp.py', 'abs_path': '/home/runner/work/sentry-python/sentry-python/tests/integrations/aiohttp/test_aiohttp.py', 'function': 'hello', 'module': 'tests.integrations.aiohttp.test_aiohttp', 'lineno': 1482, 'pre_context': [' traces_sample_rate=1.0,', ' _experiments={"trace_lifecycle": "stream"},', ' )', '', ' async def hello(request):'], 'context_line': ' 1 / 0', 'post_context': ['', ' app = web.Application()', ' app.router.add_get("/", hello)', '', ' items = capture_items("event", "span")'], 'vars': {'request': {}}, 'in_app': True}]}}]}, 'event_id': '595dd3acd8fb47ceb8b815b13297740f', 'timestamp': '2026-05-08T13:12:14.841597Z', 'contexts': {'trace': {'trace_id': '357daa0339ac4d38a585a0b806ac6cb2', 'span_id': 'b1e93bf9c589f2e8', 'parent_span_id': 'ab82f4ee25431eae', 'op': 'http.server', 'origin': 'auto.http.aiohttp'}, 'runtime': {'name': 'CPython', 'version': '3.9.25', 'build': '3.9.25 (main, Nov 3 2025, 15:14:54) \n[GCC 11.4.0]'}}, 'transaction': 'tests.integrations.aiohttp.test_aiohttp.test_server_error_span_streaming..hello', 'transaction_info': {'source': <TransactionSource.COMPONENT: 'component'>}, 'breadcrumbs': {'values': []}, 'extra': {'sys.argv': ['/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/pytest/main.py', '-W', 'error::pytest.PytestUnraisableExceptionWarning', 'tests/integrations/aiohttp', '-o', 'junit_suite_name=py3.9-aiohttp-v3.7.4']}, 'modules': {'sentry-sdk': '2.59.0', 'pytest-aiohttp': '0.3.0', 'multidict': '6.7.1', 'iniconfig': '2.1.0', 'pytest-forked': '1.6.0', 'charset-normalizer': '3.4.7', 'jsonschema': '4.25.1', 'wheel': '0.43.0', 'propcache': '0.4.1', 'tomli': '2.4.1', 'pyyaml': '6.0.3', 'coverage': '7.10.7', 'pytest-localserver': '0.10.0', 'certifi': '2026.4.22', 'hyperframe': '6.1.0', 'colorama': '0.4.6', 'pygments': '2.20.0', 'markupsafe': '3.0.3', 'referencing': '0.36.2', 'pysocks': '1.7.1', 'setuptools': '69.5.1', 'httpcore': '1.0.9', 'urllib3': '2.6.3', 'yarl': '1.22.0', 'h2': '4.3.0', 'hpack': '4.1.0', 'pytest-timeout': '2.4.0', 'asttokens': '3.0.1', 'idna': '3.13', 'py': '1.11.0', 'async-timeout': '3.0.1', 'pytest-watch': '4.2.0', 'pluggy': '1.6.0', 'aiohttp': '3.7.4', 'watchdog': '6.0.0', 'brotli': '1.2.0', 'pytest-cov': '7.1.0', 'responses': '0.26.0', 'socksio': '1.0.0', 'pip': '24.0', 'requests': '2.32.5', 'docopt': '0.6.2', 'typing_extensions': '4.15.0', 'docker': '7.1.0', 'executing': '2.2.1', 'werkzeug': '3.1.8', 'jsonschema-specifications': '2025.9.1', 'h11': '0.16.0', 'packaging': '26.2', 'chardet': '3.0.4', 'attrs': '26.1.0', 'rpds-py': '0.27.1', 'pytest': '8.4.2', 'exceptiongroup': '1.3.1'}, 'request': {'url': 'http://127.0.0.1:41929/', 'query_string': '', 'method': 'GET', 'env': {'REMOTE_ADDR': '127.0.0.1'}, 'headers': {'Host': '127.0.0.1:41929', 'sentry-trace': '357daa0339ac4d38a585a0b806ac6cb2-ab82f4ee25431eae-1', 'baggage': 'sentry-trace_id=357daa0339ac4d38a585a0b806ac6cb2,sentry-sample_rand=0.034682,sentry-environment=production,sentry-release=fe5b14821f6fcc5acfdab3744c00cc8d3876e65f,sentry-transaction=GET%20http%3A//127.0.0.1%3A41929/,sentry-sample_rate=1.0,sentry-sampled=true', 'Accept': '/', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'Python/3.9 aiohttp/3.7.4'}, 'data': None}, 'release': 'fe5b14821f6fcc5acfdab3744c00cc8d3876e65f', 'environment': 'production', 'server_name': 'runnervmrc6n4', 'sdk': {'name': 'sentry.python.aiohttp', 'version': '2.59.0', 'packages': [{'name': 'pypi:sentry-sdk', 'version': '2.59.0'}], 'integrations': ['aiohttp', 'argv', 'atexit', 'dedupe', 'excepthook', 'logging', 'modules', 'stdlib', 'threading']}, 'platform': 'python'}), UnwrappedItem(type='span', payload={'trace_id': '357daa0339ac4d38a585a0b806ac6cb2', 'span_id': 'ab82f4ee25431eae', 'name': 'GET http://127.0.0.1:41929/', 'status': 'error', 'is_segment': True, 'start_timestamp': 1778245934.837718, 'end_timestamp': 1778245934.84913, 'attributes': {'sentry.origin': 'auto.http.aiohttp', 'sentry.op': 'http.client', 'http.request.method': 'GET', 'url.full': 'http://127.0.0.1:41929/', 'thread.id': '139747850922880', 'thread.name': 'MainThread', 'process.command_args': ['/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/pytest/main.py', '-W', 'error::pytest.PytestUnraisableExceptionWarning', 'tests/integrations/aiohttp', '-o', 'junit_suite_name=py3.9-aiohttp-v3.7.4'], 'http.response.status_code': 500, 'sentry.segment.id': 'ab82f4ee25431eae', 'sentry.segment.name': 'GET http://127.0.0.1:41929/', 'sentry.sdk.name': 'sentry.python.aiohttp', 'sentry.sdk.version': '2.59.0', 'server.address': 'runnervmrc6n4', 'sentry.environment': 'production', 'sentry.release': 'fe5b14821f6fcc5acfdab3744c00cc8d3876e65f'}})])

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1496: in test_server_error_span_streaming
    assert len(items) == 3
E   assert 2 == 3
E    +  where 2 = len([UnwrappedItem(type='event', payload={'level': 'error', 'exception': {'values': [{'mechanism': {'type': 'aiohttp', 'handled': False}, 'module': None, 'type': 'ZeroDivisionError', 'value': 'division by zero', 'stacktrace': {'frames': [{'filename': 'aiohttp/web_app.py', 'abs_path': '/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/aiohttp/web_app.py', 'function': '_handle', 'module': 'aiohttp.web_app', 'lineno': 499, 'pre_context': ['                                partial(m, handler=handler), handler', '                            )', '                        else:', '                            handler = await m(app, handler)  # type: ignore', ''], 'context_line': '            resp = await handler(request)', 'post_context': ['', '        return resp', '', '    def __call__(self) -> "Application":', '        """gunicorn compatibility"""'], 'vars': {'self': {}, 'request': {}, 'loop': '<_UnixSelectorEventLoop running=True closed=False debug=False>', 'debug': 'False', 'match_info': {}, 'resp': 'None', 'expect': 'None', 'handler': '<function test_server_error_span_streaming.<locals>.hello at 0x7f1991790430>'}, 'in_app': False}, {'filename': 'tests/integrations/aiohttp/test_aiohttp.py', 'abs_path': '/home/runner/work/sentry-python/sentry-python/tests/integrations/aiohttp/test_aiohttp.py', 'function': 'hello', 'module': 'tests.integrations.aiohttp.test_aiohttp', 'lineno': 1482, 'pre_context': ['        traces_sample_rate=1.0,', '        _experiments={"trace_lifecycle": "stream"},', '    )', '', '    async def hello(request):'], 'context_line': '        1 / 0', 'post_context': ['', '    app = web.Application()', '    app.router.add_get("/", hello)', '', '    items = capture_items("event", "span")'], 'vars': {'request': {}}, 'in_app': True}]}}]}, 'event_id': '595dd3acd8fb47ceb8b815b13297740f', 'timestamp': '2026-05-08T13:12:14.841597Z', 'contexts': {'trace': {'trace_id': '357daa0339ac4d38a585a0b806ac6cb2', 'span_id': 'b1e93bf9c589f2e8', 'parent_span_id': 'ab82f4ee25431eae', 'op': 'http.server', 'origin': 'auto.http.aiohttp'}, 'runtime': {'name': 'CPython', 'version': '3.9.25', 'build': '3.9.25 (main, Nov  3 2025, 15:14:54) \n[GCC 11.4.0]'}}, 'transaction': 'tests.integrations.aiohttp.test_aiohttp.test_server_error_span_streaming.<locals>.hello', 'transaction_info': {'source': <TransactionSource.COMPONENT: 'component'>}, 'breadcrumbs': {'values': []}, 'extra': {'sys.argv': ['/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/pytest/__main__.py', '-W', 'error::pytest.PytestUnraisableExceptionWarning', 'tests/integrations/aiohttp', '-o', 'junit_suite_name=py3.9-aiohttp-v3.7.4']}, 'modules': {'sentry-sdk': '2.59.0', 'pytest-aiohttp': '0.3.0', 'multidict': '6.7.1', 'iniconfig': '2.1.0', 'pytest-forked': '1.6.0', 'charset-normalizer': '3.4.7', 'jsonschema': '4.25.1', 'wheel': '0.43.0', 'propcache': '0.4.1', 'tomli': '2.4.1', 'pyyaml': '6.0.3', 'coverage': '7.10.7', 'pytest-localserver': '0.10.0', 'certifi': '2026.4.22', 'hyperframe': '6.1.0', 'colorama': '0.4.6', 'pygments': '2.20.0', 'markupsafe': '3.0.3', 'referencing': '0.36.2', 'pysocks': '1.7.1', 'setuptools': '69.5.1', 'httpcore': '1.0.9', 'urllib3': '2.6.3', 'yarl': '1.22.0', 'h2': '4.3.0', 'hpack': '4.1.0', 'pytest-timeout': '2.4.0', 'asttokens': '3.0.1', 'idna': '3.13', 'py': '1.11.0', 'async-timeout': '3.0.1', 'pytest-watch': '4.2.0', 'pluggy': '1.6.0', 'aiohttp': '3.7.4', 'watchdog': '6.0.0', 'brotli': '1.2.0', 'pytest-cov': '7.1.0', 'responses': '0.26.0', 'socksio': '1.0.0', 'pip': '24.0', 'requests': '2.32.5', 'docopt': '0.6.2', 'typing_extensions': '4.15.0', 'docker': '7.1.0', 'executing': '2.2.1', 'werkzeug': '3.1.8', 'jsonschema-specifications': '2025.9.1', 'h11': '0.16.0', 'packaging': '26.2', 'chardet': '3.0.4', 'attrs': '26.1.0', 'rpds-py': '0.27.1', 'pytest': '8.4.2', 'exceptiongroup': '1.3.1'}, 'request': {'url': 'http://127.0.0.1:41929/', 'query_string': '', 'method': 'GET', 'env': {'REMOTE_ADDR': '127.0.0.1'}, 'headers': {'Host': '127.0.0.1:41929', 'sentry-trace': '357daa0339ac4d38a585a0b806ac6cb2-ab82f4ee25431eae-1', 'baggage': 'sentry-trace_id=357daa0339ac4d38a585a0b806ac6cb2,sentry-sample_rand=0.034682,sentry-environment=production,sentry-release=fe5b14821f6fcc5acfdab3744c00cc8d3876e65f,sentry-transaction=GET%20http%3A//127.0.0.1%3A41929/,sentry-sample_rate=1.0,sentry-sampled=true', 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'Python/3.9 aiohttp/3.7.4'}, 'data': None}, 'release': 'fe5b14821f6fcc5acfdab3744c00cc8d3876e65f', 'environment': 'production', 'server_name': 'runnervmrc6n4', 'sdk': {'name': 'sentry.python.aiohttp', 'version': '2.59.0', 'packages': [{'name': 'pypi:sentry-sdk', 'version': '2.59.0'}], 'integrations': ['aiohttp', 'argv', 'atexit', 'dedupe', 'excepthook', 'logging', 'modules', 'stdlib', 'threading']}, 'platform': 'python'}), UnwrappedItem(type='span', payload={'trace_id': '357daa0339ac4d38a585a0b806ac6cb2', 'span_id': 'ab82f4ee25431eae', 'name': 'GET http://127.0.0.1:41929/', 'status': 'error', 'is_segment': True, 'start_timestamp': 1778245934.837718, 'end_timestamp': 1778245934.84913, 'attributes': {'sentry.origin': 'auto.http.aiohttp', 'sentry.op': 'http.client', 'http.request.method': 'GET', 'url.full': 'http://127.0.0.1:41929/', 'thread.id': '139747850922880', 'thread.name': 'MainThread', 'process.command_args': ['/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/pytest/__main__.py', '-W', 'error::pytest.PytestUnraisableExceptionWarning', 'tests/integrations/aiohttp', '-o', 'junit_suite_name=py3.9-aiohttp-v3.7.4'], 'http.response.status_code': 500, 'sentry.segment.id': 'ab82f4ee25431eae', 'sentry.segment.name': 'GET http://127.0.0.1:41929/', 'sentry.sdk.name': 'sentry.python.aiohttp', 'sentry.sdk.version': '2.59.0', 'server.address': 'runnervmrc6n4', 'sentry.environment': 'production', 'sentry.release': 'fe5b14821f6fcc5acfdab3744c00cc8d3876e65f'}})])

test_http_exception_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 403 + where 500 = <ClientResponse(http://127.0.0.1:33723/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:15 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1542: in test_http_exception_span_streaming
    assert resp.status == 403
E   AssertionError: assert 500 == 403
E    +  where 500 = <ClientResponse(http://127.0.0.1:33723/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:15 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_http_exception_ok_status_not_overridden_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 500 == 302 + where 500 = <ClientResponse(http://127.0.0.1:41277/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:15 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1580: in test_http_exception_ok_status_not_overridden_span_streaming
    assert resp.status == 302
E   AssertionError: assert 500 == 302
E    +  where 500 = <ClientResponse(http://127.0.0.1:41277/) [500 Internal Server Error]>\n<CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '55', 'Date': 'Fri, 08 May 2026 13:12:15 GMT', 'Server': 'Python/3.9 aiohttp/3.7.4', 'Connection': 'close')>\n.status

test_outgoing_client_span_span_streaming[pyloop]

File: tests.integrations.aiohttp.test_aiohttp
Suite: py3.9-aiohttp-v3.7.4
Error: AssertionError: assert 1 == 3 + where 1 = len([UnwrappedItem(type='span', payload={'trace_id': '96650ac078bc44d3a53c8b0a24c75a6c', 'span_id': '9bce2b81809406c2', 'name': 'GET http://127.0.0.1:41523/', 'status': 'error', 'is_segment': True, 'start_timestamp': 1778245935.378089, 'end_timestamp': 1778245935.623357, 'attributes': {'sentry.origin': 'auto.http.aiohttp', 'sentry.op': 'http.client', 'http.request.method': 'GET', 'url.full': 'http://127.0.0.1:41523/', 'thread.id': '139747850922880', 'thread.name': 'MainThread', 'process.command_args': ['/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/pytest/main.py', '-W', 'error::pytest.PytestUnraisableExceptionWarning', 'tests/integrations/aiohttp', '-o', 'junit_suite_name=py3.9-aiohttp-v3.7.4'], 'http.response.status_code': 500, 'code.line.number': 1624, 'code.namespace': 'tests.integrations.aiohttp.test_aiohttp', 'code.file.path': 'tests/integrations/aiohttp/test_aiohttp.py', 'code.function': 'test_outgoing_client_span_span_streaming', 'sentry.segment.id': '9bce2b81809406c2', 'sentry.segment.name': 'GET http://127.0.0.1:41523/', 'sentry.sdk.name': 'sentry.python.aiohttp', 'sentry.sdk.version': '2.59.0', 'server.address': 'runnervmrc6n4', 'sentry.environment': 'production', 'sentry.release': 'fe5b14821f6fcc5acfdab3744c00cc8d3876e65f'}})])

Stack Trace
tests/integrations/aiohttp/test_aiohttp.py:1632: in test_outgoing_client_span_span_streaming
    assert len(items) == 3
E   AssertionError: assert 1 == 3
E    +  where 1 = len([UnwrappedItem(type='span', payload={'trace_id': '96650ac078bc44d3a53c8b0a24c75a6c', 'span_id': '9bce2b81809406c2', 'name': 'GET http://127.0.0.1:41523/', 'status': 'error', 'is_segment': True, 'start_timestamp': 1778245935.378089, 'end_timestamp': 1778245935.623357, 'attributes': {'sentry.origin': 'auto.http.aiohttp', 'sentry.op': 'http.client', 'http.request.method': 'GET', 'url.full': 'http://127.0.0.1:41523/', 'thread.id': '139747850922880', 'thread.name': 'MainThread', 'process.command_args': ['/home/runner/work/sentry-python/sentry-python/.tox/py3.9-aiohttp-v3.7.4/lib/python3.9/site-packages/pytest/__main__.py', '-W', 'error::pytest.PytestUnraisableExceptionWarning', 'tests/integrations/aiohttp', '-o', 'junit_suite_name=py3.9-aiohttp-v3.7.4'], 'http.response.status_code': 500, 'code.line.number': 1624, 'code.namespace': 'tests.integrations.aiohttp.test_aiohttp', 'code.file.path': 'tests/integrations/aiohttp/test_aiohttp.py', 'code.function': 'test_outgoing_client_span_span_streaming', 'sentry.segment.id': '9bce2b81809406c2', 'sentry.segment.name': 'GET http://127.0.0.1:41523/', 'sentry.sdk.name': 'sentry.python.aiohttp', 'sentry.sdk.version': '2.59.0', 'server.address': 'runnervmrc6n4', 'sentry.environment': 'production', 'sentry.release': 'fe5b14821f6fcc5acfdab3744c00cc8d3876e65f'}})])

❌ Patch coverage is 45.00%. Project has 16033 uncovered lines.

Files with missing lines (3)
File Patch % Lines
utils.py 54.32% ⚠️ 428 Missing and 90 partials
client.py 61.82% ⚠️ 210 Missing and 78 partials
consts.py 99.22% ⚠️ 2 Missing

Generated by Codecov Action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add before_send_span

1 participant