Skip to content

fix: close the CCIP-read aiohttp session on every exit path - #3913

Open
franco-gondi wants to merge 1 commit into
ApeWorX:mainfrom
franco-gondi:fix/ccip-read-session-leak
Open

franco-gondi wants to merge 1 commit into
ApeWorX:mainfrom
franco-gondi:fix/ccip-read-session-leak

Conversation

@franco-gondi

Copy link
Copy Markdown

What was wrong?

async_handle_offchain_lookup (the async CCIP-read / EIP-3668 handler) opened a bare ClientSession() and closed it by hand before each return and raise. An exception it did not anticipate skipped the close and leaked the session along with its pooled connection. asyncio then logs Unclosed client session and Unclosed connector when the session is garbage-collected.

The common trigger is a gateway that answers 2xx with a body that isn't JSON (e.g. text/html). await response.json() raises aiohttp.ContentTypeError after the body has been read and the connection released to the pool. A JSON body that isn't a dict, or a cancelled task, leaks the session the same way.

How was it fixed?

The session now lives in async with ClientSession() as session:, so it closes on every exit path, and the manual await session.close() calls are gone. The rest of the function is only re-indented.

Adds test_async_offchain_resolution_closes_session_when_response_is_not_json. It mocks a gateway response whose json() raises and asserts the session was closed. The test fails before the change and passes after.

async_handle_offchain_lookup opened a bare ClientSession() and closed it
by hand before each return and raise. Any exception it did not anticipate
skipped the close and leaked the session together with its pooled
connection, which asyncio then logs as "Unclosed client session" and
"Unclosed connector". For example: response.json() raising
ContentTypeError on a 2xx gateway reply that is not JSON, a JSON body
that is not a dict, or cancellation.

Wrapping the session in `async with` closes it on every path. Adds a
regression test where the gateway response's json() raises.

Claude-Session: https://claude.ai/code/session_01LDYugMbgucFoMVbtMY5SJx
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.

1 participant