codeant-ai-for-open-source[bot] commented on code in PR #39917:
URL: https://github.com/apache/superset/pull/39917#discussion_r3202961384


##########
superset/mcp_service/auth.py:
##########
@@ -516,6 +516,45 @@ def _cleanup_session_on_error() -> None:
         logger.warning("Error cleaning up session after exception: %s", e)
 
 
+def _remove_session_safe() -> None:
+    """Remove the scoped SQLAlchemy session, tolerating SSL/connection errors.
+
+    Thread-pool workers reuse threads across requests.  Before each tool call
+    the session is removed to prevent a prior request's thread-local session
+    from leaking into the next one.  If the underlying DBAPI connection died
+    between requests (e.g. RDS SSL idle-timeout or max-connection-age), the
+    rollback implicit in ``session.close()`` raises ``OperationalError``.
+
+    When that happens:
+    1. Invalidate the dead connection so the pool discards it (rather than
+       returning a broken connection to the next caller).
+    2. Retry ``remove()`` to deregister the session from the scoped registry.
+
+    The tool call still proceeds because a fresh connection will be obtained
+    on the next DB access.
+    """
+    from sqlalchemy.exc import OperationalError
+
+    from superset.extensions import db
+
+    try:
+        db.session.remove()
+    except OperationalError as exc:

Review Comment:
   **Suggestion:** Catching only `OperationalError` is too narrow for 
disconnect scenarios across drivers, because SQLAlchemy can surface dropped 
connections as other `DBAPIError` subclasses (for example `InterfaceError`). In 
those cases this code path is skipped and pre-call cleanup still crashes; 
broaden handling to disconnect-related DBAPI errors and gate on 
connection-invalidated semantics. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Sync MCP tools fail on non-OperationalError disconnects.
   - ⚠️ Connection drop handling inconsistent across database drivers.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. `sync_wrapper()` in `superset/mcp_service/auth.py:670-714` wraps sync MCP 
tools
   registered via `@tool` (see `superset/core/mcp/core_mcp_injection.py:26-43`) 
and calls
   `_remove_session_safe()` at line 680 before any user lookup or tool logic, 
so any
   exception from `_remove_session_safe()` aborts the tool call during pre-call 
teardown.
   
   2. `_remove_session_safe()` in `superset/mcp_service/auth.py:519-555` imports
   `sqlalchemy.exc.OperationalError` (line 536), calls `db.session.remove()` 
(line 540), and
   only catches `OperationalError` in `except OperationalError as exc:` at line 
542; any
   other `sqlalchemy.exc.DBAPIError` subclass from `db.session.remove()` is not 
handled here
   and will propagate out of `sync_wrapper()`.
   
   3. Superset elsewhere relies on `sqlalchemy.exc.DBAPIError` with 
`.connection_invalidated`
   to detect disconnects generically, e.g. `superset/utils/core.py:771-775` 
catches
   `exc.DBAPIError as err` and checks `err.connection_invalidated` to decide 
whether to treat
   the exception as a disconnect and transparently revalidate the connection, 
showing that
   connection drops are not assumed to always be `OperationalError`.
   
   4. To reproduce using the same call path as the existing SSL-idle test
   (`tests/unit_tests/mcp_service/test_auth_user_resolution.py:33-73`), patch
   `superset.extensions.db.session.remove` so that the first call raises a
   `sqlalchemy.exc.DBAPIError` instance with `connection_invalidated=True` 
(similar to the
   pattern in `utils/core.py:771-775`) instead of `OperationalError`, then 
invoke `wrapped =
   mcp_auth_hook(dummy_tool)` and call `wrapped()`: `_remove_session_safe()` at
   `auth.py:540-542` will not catch this DBAPIError, causing the pre-call 
session cleanup to
   raise and abort the sync tool, even though this is a classic disconnect 
scenario where a
   new connection could be established on the next DB access.
   ```
   </details>
   
   [Fix in 
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset%2Fmcp_service%2Fauth.py%0A%2A%2ALine%3A%2A%2A%20542%3A542%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20Catching%20only%20%60OperationalError%60%20is%20too%20narrow%20for%20disconnect%20scenarios%20across%20drivers%2C%20because%20SQLAlchemy%20can%20surface%20dropped%20connections%20as%20other%20%60DBAPIError%60%20subclasses%20%28for%20example%20%60InterfaceError%60%29.%20In%20those%20cases%20this%20code%20path%20is%20skipped%20and%20pre-call%20cleanup%20still%20crashes%3B%20broaden%20handling%20to%20disconnect-related%20DBAPI%20errors%20and%20gate%20on%20connection-invalidated%20semantics.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%2
 
0implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
 | [Fix in VSCode 
Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset%2Fmcp_service%2Fauth.py%0A%2A%2ALine%3A%2A%2A%20542%3A542%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20Catching%20only%20%60OperationalError%60%20is%20too%20narrow%20for%20disconnect%20scenarios%20across%20drivers%2C%20because%20SQLAlchemy%20can%20surface%20dropped%20connections%20as%20other%20%60DBAPIError%60%20subclasses%20%28for%20example%20%60InterfaceError%60%29.%20In%20those%20cases%20this%20code%20path%20is%20skipped%20and%20pre-call%20cleanup%20still%20crashes%3B%20broaden%20handling
 
%20to%20disconnect-related%20DBAPI%20errors%20and%20gate%20on%20connection-invalidated%20semantics.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/auth.py
   **Line:** 542:542
   **Comment:**
        *Logic Error: Catching only `OperationalError` is too narrow for 
disconnect scenarios across drivers, because SQLAlchemy can surface dropped 
connections as other `DBAPIError` subclasses (for example `InterfaceError`). In 
those cases this code path is skipped and pre-call cleanup still crashes; 
broaden handling to disconnect-related DBAPI errors and gate on 
connection-invalidated semantics.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39917&comment_hash=c20749ebfd39120c11fd1570aa512a8dd888987e943924d804be7f8ab99ae952&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39917&comment_hash=c20749ebfd39120c11fd1570aa512a8dd888987e943924d804be7f8ab99ae952&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to