mikebridge opened a new pull request, #45472:
URL: https://github.com/apache/superset/pull/45472

   ### SUMMARY
   
   **TL;DR:** Copying a dashboard with a layout that leaves out some of the 
source dashboard's current charts failed with a generic `400 Arguments are not 
correct`, and nothing was logged. This PR fixes the copy and logs the cause 
when a copy fails.
   
   **Background.** In version history, "Open as new dashboard" forks an older 
version by posting that version's layout to `POST /api/v1/dashboard/<id>/copy/` 
(without `duplicate_slices`). The copy endpoint rebuilds the new dashboard's 
charts from `json_metadata.positions`.
   
   **Problem.** `DashboardDAO.copy_dashboard` first linked all of the source's 
current charts to the new dashboard (`dash.slices = original_dash.slices`). 
Then `set_dash_metadata` replaced that list with the charts in the layout. For 
each chart the layout dropped, the chart's unloaded `Slice.dashboards` backref 
collection was left holding a queued append followed by a remove. On flush, 
SQLAlchemy issued `DELETE FROM dashboard_slices` for a row that was never 
inserted. That raised `StaleDataError`, which the command's transaction handler 
turned into `DashboardCopyError`, and the API returned the generic 400. 
`on_error` logs only exceptions that carry an `exception` attribute, so nothing 
was logged.
   
   Any older version that doesn't contain every chart the dashboard has today 
hits this. It also hits an empty layout. It happens on PostgreSQL and SQLite 
alike.
   
   **Changes.**
   - `DashboardDAO.copy_dashboard` links the source's charts only when no 
layout is sent. With a layout, `set_dash_metadata` remains the only place that 
sets membership. The `duplicate_slices` path is unchanged, and the integration 
test covers it with partial and empty layouts too.
   - `copy_dash` logs `DashboardCopyError` with `exc_info`, so the underlying 
database error appears in the logs. The response is unchanged. The log sits in 
the REST route so the shared `on_error` helper, which every command's 
transaction uses, keeps its behavior. The MCP duplicate tool still reports the 
error without logging its cause.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A (API behavior).
   
   Before: `POST /api/v1/dashboard/<id>/copy/` with a layout that omits a 
current chart returns `400 {"message": "Arguments are not correct"}`. After: it 
returns `200`, and the new dashboard has exactly the charts in the layout. The 
source dashboard is unchanged.
   
   ### TESTING INSTRUCTIONS
   
   - Unit (SQLite): `pytest 
tests/unit_tests/dao/test_copy_dashboard_legacy_ids.py -k dropped_from_layout`. 
It fails with `StaleDataError` before the fix.
   - Integration (run on PostgreSQL): `pytest 
tests/integration_tests/dashboards/api_tests.py -k 
"copy_dashboard_layout_without_current_charts or 
copy_dashboard_logs_database_error"`. Both fail before the fix.
   - Manually: with version history on, add a chart to a dashboard, then open 
an earlier version in version history and choose "Open as new dashboard". The 
new dashboard opens with that version's charts.
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API
   


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