aminghadersohi commented on code in PR #37183:
URL: https://github.com/apache/superset/pull/37183#discussion_r2775339375


##########
superset/mcp_service/chart/tool/get_chart_info.py:
##########
@@ -36,6 +36,22 @@
 logger = logging.getLogger(__name__)
 
 
+def _get_cached_form_data(form_data_key: str) -> str | None:
+    """Retrieve form_data from cache using form_data_key.
+
+    Returns the JSON string of form_data if found, None otherwise.
+    """
+    from superset.commands.explore.form_data.get import GetFormDataCommand
+    from superset.commands.explore.form_data.parameters import 
CommandParameters
+
+    try:
+        cmd_params = CommandParameters(key=form_data_key)
+        return GetFormDataCommand(cmd_params).run()
+    except Exception as e:
+        logger.warning("Failed to retrieve form_data from cache: %s", e)
+        return None

Review Comment:
   MCP tools sit at a system boundary (like API endpoints) and must always 
return structured error responses to clients, never propagate raw exceptions. 
The broad `except Exception` is intentional here — catching only specific 
exceptions would let unexpected errors (TypeError, AttributeError, etc.) bubble 
up unhandled to MCP clients.



##########
superset/mcp_service/chart/tool/get_chart_info.py:
##########
@@ -83,9 +111,41 @@ async def get_chart_info(
     result = tool.run_tool(request.identifier)
 
     if isinstance(result, ChartInfo):
+        # If form_data_key is provided, override form_data with cached version
+        if request.form_data_key:
+            await ctx.info(
+                "Retrieving unsaved chart state from cache: form_data_key=%s"
+                % (request.form_data_key,)
+            )
+            cached_form_data = _get_cached_form_data(request.form_data_key)
+
+            if cached_form_data:
+                try:
+                    result.form_data = utils_json.loads(cached_form_data)
+                    result.form_data_key = request.form_data_key
+                    result.is_unsaved_state = True
+
+                    # Update viz_type from cached form_data if present
+                    if result.form_data and "viz_type" in result.form_data:
+                        result.viz_type = result.form_data["viz_type"]
+
+                    await ctx.info(
+                        "Chart form_data overridden with unsaved state from 
cache"
+                    )
+                except Exception as e:
+                    await ctx.warning(
+                        "Failed to parse cached form_data: %s. "
+                        "Using saved chart configuration." % (str(e),)

Review Comment:
   MCP tools sit at a system boundary and must always return structured error 
responses. The broad exception catch ensures unexpected errors are converted to 
proper error responses rather than crashing the tool.



##########
superset/mcp_service/chart/tool/get_chart_data.py:
##########
@@ -42,6 +42,22 @@
 logger = logging.getLogger(__name__)
 
 
+def _get_cached_form_data(form_data_key: str) -> str | None:
+    """Retrieve form_data from cache using form_data_key.
+
+    Returns the JSON string of form_data if found, None otherwise.
+    """
+    from superset.commands.explore.form_data.get import GetFormDataCommand
+    from superset.commands.explore.form_data.parameters import 
CommandParameters
+
+    try:
+        cmd_params = CommandParameters(key=form_data_key)
+        return GetFormDataCommand(cmd_params).run()
+    except Exception as e:

Review Comment:
   The inner helper `_get_cached_form_data` uses specific exceptions (KeyError, 
ValueError, CommandException) which is appropriate — it's a helper that should 
catch known failure modes. The outer tool-level exception handlers use broad 
`except Exception` intentionally because MCP tools must always return 
structured errors to clients.



##########
superset/mcp_service/dashboard/tool/get_dashboard_info.py:
##########
@@ -40,6 +41,23 @@
 logger = logging.getLogger(__name__)
 
 
+def _get_permalink_state(permalink_key: str) -> Dict[str, Any] | None:
+    """Retrieve dashboard filter state from permalink.
+
+    Returns the permalink value containing dashboardId and state if found,
+    None otherwise.
+    """
+    from superset.commands.dashboard.permalink.get import 
GetDashboardPermalinkCommand
+
+    try:
+        result = GetDashboardPermalinkCommand(permalink_key).run()
+        # Convert TypedDict to regular dict for type compatibility
+        return dict(result) if result else None
+    except Exception as e:

Review Comment:
   MCP tools sit at a system boundary and must always return structured error 
responses (DashboardError in this case). The broad `except Exception` is 
intentional — narrower catches would let unexpected errors propagate unhandled 
to MCP clients.



-- 
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