Skip to content

Conversation

@cofin
Copy link
Member

@cofin cofin commented Oct 6, 2025

Summary

Fixes a RuntimeError: generator raised StopIteration that prevented the BigQuery emulator fixture from starting Docker containers. This issue affected BigQuery tests and could potentially impact other database services under certain conditions.

Root Cause

The error occurred in _service.py:188 where next() was used without a default value inside a @contextmanager generator function:

host_port = int(
    container.ports[next(k for k in container.ports if k.startswith(str(container_port)))][0]["HostPort"]
)

When no matching port key was found, next() raised StopIteration. Since Python 3.7+, StopIteration inside a generator is converted to RuntimeError, causing the cryptic error message.

Changes

1. Enhanced retry loop (lines 178-182)

  • Before: container.reload() called after checking ports
  • After: container.reload() called before checking ports
  • Why: Ensures fresh port bindings are available on each retry iteration

2. Safe port lookup with exact-key matching (lines 187-196)

  • Before: Used next() with startswith() pattern matching
  • After: Uses explicit dict.get() with exact protocol keys ("9050/tcp", "9050/udp")
  • Benefits:
    • Eliminates StopIteration exceptions
    • Avoids false positives (e.g., "80" matching "8080/tcp")
    • Provides descriptive error messages showing available ports
    • Uses RuntimeError for consistency with fixture setup failures

cofin added 2 commits October 6, 2025 02:24
Fixes a RuntimeError caused by StopIteration being raised inside a
generator function when Docker container ports cannot be found.

Changes:
- Move container.reload() to the start of retry loop to ensure fresh
  port bindings are available
- Replace unsafe next() call with explicit dict.get() for exact-key
  port matching (e.g., "9050/tcp" instead of startswith pattern)
- Add descriptive error message showing available ports when lookup fails
- Use RuntimeError instead of allowing StopIteration to propagate

This fix ensures all database services (including BigQuery emulator)
can properly start their Docker containers and expose ports reliably.

Resolves issue where BigQuery tests failed with:
"RuntimeError: generator raised StopIteration"
@cofin cofin changed the title fix: resolve StopIteration error in BigQuery emulator fixture fix: resolve 1StopIteration1 error in BigQuery emulator fixture Oct 6, 2025
@cofin cofin changed the title fix: resolve 1StopIteration1 error in BigQuery emulator fixture fix: resolve StopIteration error in BigQuery emulator fixture Oct 6, 2025
@cofin
Copy link
Member Author

cofin commented Oct 6, 2025

Updated to make the protocol configurable instead of implicitly trying UDP. Added a protocol parameter (default: "tcp") that accepts:

  • "tcp" - only check TCP ports
  • "udp" - only check UDP ports
  • "both" - try TCP first, fallback to UDP

This way services that need UDP can explicitly opt-in via protocol="udp" or protocol="both".

@cofin cofin merged commit 4152dd4 into main Oct 6, 2025
14 checks passed
@cofin cofin deleted the stop-iteration branch October 6, 2025 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants