fix(mcp): stop masking dashboard lookup DB errors as not-found#41919
Conversation
update_dashboard's _find_and_authorize_dashboard caught DashboardNotFoundError and SQLAlchemyError together, returning "Dashboard not found" for real database/infra failures with zero server-side logging. Split the handlers: SQLAlchemyError is now logged via logger.exception and returned as a distinct, sanitized DatabaseError (no raw exception text leaked to the LLM client), matching the pattern already used in generate_dashboard.py.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #41919 +/- ##
==========================================
- Coverage 64.74% 64.74% -0.01%
==========================================
Files 2738 2738
Lines 152950 152953 +3
Branches 35055 35055
==========================================
Hits 99032 99032
- Misses 52018 52021 +3
Partials 1900 1900
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR fixes error classification/observability for the update_dashboard MCP tool by ensuring database/infrastructure failures during dashboard lookup are not misreported as “not found”, and are instead logged server-side with a distinct structured error response.
Changes:
- Split
_find_and_authorize_dashboardexception handling soDashboardNotFoundErrorreturnsDashboardNotFound, whileSQLAlchemyErrorlogs vialogger.exceptionand returnsDatabaseErrorwith a generic message. - Added a unit test asserting the DB-error path returns
error_type="DatabaseError", does not include the raw exception text, and triggers server-side logging.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
superset/mcp_service/dashboard/tool/update_dashboard.py |
Separates not-found vs DB lookup failures; logs SQLAlchemy exceptions and returns a distinct DatabaseError without leaking DB details in the response. |
tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py |
Adds coverage to ensure DB lookup failures aren’t masked as not-found and are logged. |
Code Review Agent Run #4dc1e5Actionable Suggestions - 0Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
SUMMARY
update_dashboard's_find_and_authorize_dashboardhelper caughtDashboardNotFoundErrorandSQLAlchemyErrorin the sameexceptclause, returning aDashboardNotFoundresponse for both. A real database/infrastructure failure during the dashboard lookup was therefore misreported to the caller as "dashboard not found," with zero server-side logging of the underlying error — invisible to operators and misleading to the MCP client.This splits the handling:
DashboardNotFoundErrorstill returns the existingDashboardNotFoundstructured error.SQLAlchemyErroris now logged server-side vialogger.exceptionand returns a distinctDatabaseErrorwith a generic message. The raw exception text is never included in the response, sincestr(exc)on aSQLAlchemyErrorcan leak table/column/constraint names — same leak-avoidance pattern already used ingenerate_dashboard.py.Audited the rest of the dashboard domain (
add_chart_to_existing_dashboard.py,remove_chart_from_dashboard.py,duplicate_dashboard.py,manage_native_filters.py) and the widermcp_servicepackage for the same "SQLAlchemyError collapsed into not-found" pattern; no other occurrence exists.BEFORE/AFTER
Before: A transient DB error during
update_dashboard's lookup returned{"error": "Dashboard not found: ...", "error_type": "DashboardNotFound"}with no log line anywhere.After: The same failure returns
{"error": "Failed to look up dashboard due to a database error.", "error_type": "DatabaseError"}and is logged server-side vialogger.exception(with traceback) for observability.TESTING INSTRUCTIONS
pytest tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py -q— 15 passed, including a new test asserting the DB-error path returnserror_type="DatabaseError", never leaks the raw exception text, and callslogger.exception.pytest tests/unit_tests/mcp_service/dashboard/ -q— 265 passed (no regressions).ADDITIONAL INFORMATION