From 18918766bcccbb682241ac5b5b17d0bce9e23ca0 Mon Sep 17 00:00:00 2001 From: Sahith Reddy Thummala Date: Sat, 1 Aug 2026 18:36:09 -0400 Subject: [PATCH 1/2] fix: add logging to empty exception handlers in _base_client.py --- src/openai/_base_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openai/_base_client.py b/src/openai/_base_client.py index 10d7b9f7ca..9b06d8ca28 100644 --- a/src/openai/_base_client.py +++ b/src/openai/_base_client.py @@ -894,7 +894,7 @@ def __del__(self) -> None: try: self.close() except Exception: - pass + log.debug("Failed to close client", exc_info=True) class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]): @@ -1520,7 +1520,7 @@ def __del__(self) -> None: # TODO(someday): support non asyncio runtimes here asyncio.get_running_loop().create_task(self.aclose()) except Exception: - pass + log.debug("Failed to close async client", exc_info=True) class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]): From c702652ca3a5c9c23bfff0267378f82c0fa11d0b Mon Sep 17 00:00:00 2001 From: Sahith Reddy Thummala Date: Mon, 3 Aug 2026 22:15:04 -0400 Subject: [PATCH 2/2] fix: keep __del__ finalizers silent with explanatory comments These handlers live inside __del__ finalizers, not regular call paths. Logging here is problematic for two reasons: 1. asyncio.get_running_loop() raises RuntimeError whenever __del__ runs outside an active event loop, which is the normal case during GC and interpreter shutdown. Logging that as an error is misleading. 2. exc_info=True dumps raw tracebacks that may contain transport/proxy exception text not sanitized by SensitiveHeadersFilter. Keeping pass and documenting why is the correct approach for finalizers. --- src/openai/_base_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openai/_base_client.py b/src/openai/_base_client.py index 9b06d8ca28..90ae56b7cc 100644 --- a/src/openai/_base_client.py +++ b/src/openai/_base_client.py @@ -894,7 +894,7 @@ def __del__(self) -> None: try: self.close() except Exception: - log.debug("Failed to close client", exc_info=True) + pass # best-effort; __del__ may run during interpreter teardown class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]): @@ -1520,7 +1520,7 @@ def __del__(self) -> None: # TODO(someday): support non asyncio runtimes here asyncio.get_running_loop().create_task(self.aclose()) except Exception: - log.debug("Failed to close async client", exc_info=True) + pass # expected when no event loop is running (GC / interpreter shutdown) class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):