Skip to content

.

3869fad
Select commit
Loading
Failed to load commit list.
Merged

feat(redis): Support streaming spans #6083

.
3869fad
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Apr 23, 2026 in 9m 53s

6 issues

Medium

Spans not closed on Redis command exception - `sentry_sdk/integrations/redis/_async_common.py:145-158`

When old_execute_command raises an exception (e.g., Redis connection error), db_span.__exit__() and cache_span.__exit__() are never called because they're not wrapped in a try/finally block. This causes span leaks where spans remain open without proper cleanup. Other integrations like graphene.py correctly use try/finally to ensure __exit__ is always called.

Also found at:

  • sentry_sdk/integrations/redis/_sync_common.py:151-152
Test parameter 'expected_first_ten' is unused when span_streaming=True - `tests/integrations/redis/cluster/test_redis_cluster.py:152-153`

The expected_first_ten parameter is defined via @pytest.mark.parametrize but is only used in the else branch (non-streaming path) at line 207. When span_streaming=True, this parameter is accepted but never asserted, meaning the test doesn't verify that command filtering works correctly in streaming mode. This creates a false sense of test coverage for the send_default_pii feature in the streaming path.

Also found at:

  • tests/integrations/redis/test_redis.py:72-90
Test asserts wrong span index for cache.hit check - `tests/integrations/redis/test_redis_cache_module_async.py:293`

Line 293 checks spans[1]["data"] for the absence of cache.hit, but the surrounding context is asserting properties of spans[2] (the cache.put span). This appears to be a typo where spans[1] should be spans[2]. As written, the test may pass incorrectly if spans[1] (db.redis) happens to not have cache.hit, even if spans[2] incorrectly contains it.

Also found at:

  • tests/integrations/redis/test_redis_cache_module.py:330
Spans leak and are never closed when Redis command raises exception - `sentry_sdk/integrations/redis/_async_common.py:145-152`

In _sentry_execute_command, both db_span and cache_span are entered via manual __enter__() calls but if old_execute_command raises an exception (e.g., connection error, timeout), the __exit__() calls on lines 152 and 158 are never reached. This leaves spans in an invalid state on the scope, potentially affecting parent span state and causing resource leaks. The spans should be wrapped in try/finally blocks to ensure proper cleanup.

Also found at:

  • sentry_sdk/integrations/redis/_sync_common.py:151-160
Test asserts wrong DB_DRIVER_NAME value for streaming spans - `tests/integrations/redis/test_redis.py:405`

The test test_db_connection_attributes_client asserts that attrs[SPANDATA.DB_DRIVER_NAME] equals "redis" for span streaming mode (line 405), but the implementation in sentry_sdk/integrations/redis/modules/queries.py line 55 sets it to "redis-py". This mismatch will cause the test to fail when executed.

Also found at:

  • tests/integrations/redis/test_redis.py:456

Low

Test assertion checks wrong span index - will always pass trivially - `tests/integrations/redis/test_redis_cache_module_async.py:293`

Line 293 asserts "cache.hit" not in spans[1]["data"] but spans[1] is a db.redis span (as indicated by the comment on line 286), not the cache.put span being tested. The intent is to verify that cache.put operations (spans[2]) don't have a cache.hit attribute. Since db.redis spans never have cache.hit, this assertion always passes trivially and fails to test the actual behavior.

Also found at:

  • tests/integrations/redis/test_redis_cache_module.py:330
4 skills analyzed
Skill Findings Duration Cost
code-review 3 3m 53s $3.46
find-bugs 3 7m 44s $6.34
skill-scanner 0 8m 4s $0.89
security-review 0 9m 32s $1.40

Duration: 29m 13s · Tokens: 8.2M in / 97.9k out · Cost: $12.13 (+merge: $0.01, +fix_gate: $0.01, +dedup: $0.01, +extraction: $0.02)