Companion to the previous commit's positive per-tile readiness check,
carrying the rest of PR #42119's changes onto this base:
- Per-tile readiness timeout logs at WARNING (customer chart-loading
issue, not a system fault -- matching #38130/#38441) with elapsed wait
time, tile index/total, load_wait, and the identity + stuck-state of
each unready chart holder (waiting_on_database / spinner_mounted /
nothing_mounted), then re-raises so the report fails rather than
shipping a blank or spinner tile. A per-tile DEBUG line logs readiness
wait time for profiling.
- The deliberate readiness-timeout re-raise is tracked with an explicit
flag rather than `except PlaywrightTimeout` at the outer level, since
PlaywrightTimeout is aliased to bare Exception when playwright isn't
installed and would otherwise swallow-or-propagate the wrong cases.
- Threads an optional log_context (e.g. "execution_id=<uuid>") from
BaseReportState._get_screenshots through BaseScreenshot.get_screenshot
and both WebDriverProxy implementations into take_tiled_screenshot,
so timeout logs correlate back to the report run. Defaults to None
for callers outside the report pipeline (thumbnails).
Backported from apache/superset#42119 (commits 37da786b52, f6feb70eca,
97d15485ad squashed) onto this branch's base; only the log lines this
change itself adds or touches carry the context suffix -- pre-existing
log lines on this base (f-string style) are left as-is.
Co-Authored-By: Claude <noreply@anthropic.com>
`take_tiled_screenshot()` waited for the *absence* of `.loading` elements
visible in the viewport before capturing each tile. With
DashboardVirtualization on (default), a chart holder that has just scrolled
into view but hasn't fired its IntersectionObserver callback yet mounts
neither a spinner nor a chart, so the predicate passed vacuously and the
tile was captured blank. On top of that, a per-tile timeout was caught,
logged as a warning, and the tile was captured anyway -- delivering a
spinner screenshot to report recipients instead of failing the report.
Replace the absence-of-`.loading` predicate with a positive readiness
check: every chart holder (`data-test="dashboard-component-chart-holder"`)
intersecting the viewport must show a terminal state (a rendered chart via
`.slice_container`, or an error/empty state via `[role="alert"]` /
`.ant-empty` / `.missing-chart-container`) before a tile is captured. A
holder with nothing mounted no longer satisfies the wait.
A per-tile timeout is now logged at ERROR with the tile index, the
load_wait, and the identities of the still-unready chart holders, and
re-raises instead of being swallowed -- the report now fails
(ReportScheduleScreenshotFailedError) instead of silently shipping a
degraded screenshot.
Co-Authored-By: Claude <noreply@anthropic.com>
The antd Table onChange callback in TableCollection fires for pagination,
filter, and sort changes alike. With an active sorter, every page click
re-dispatched setSortBy with a new array instance; react-table's
usePagination (autoResetPage) resets pageIndex whenever the sortBy state
identity changes, which cancelled the navigation. Sorting a column in any
client-paginated TableView (e.g. the dashboard 'View as table' pane) made
the pagination controls unresponsive, and ListView/server pagination
triggered a spurious page-1 refetch.
Gate the sort dispatch on antd's extra.action so only genuine sorter
changes reach setSortBy.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Homebrew rolled out an untrusted-tap security change on the GitHub runner
image that makes `brew install norwoodj/tap/helm-docs` fail with "Skipping
norwoodj/tap because it is not trusted", so the pre-commit workflow's
"Enable brew and helm-docs" step now exits non-zero before the hooks ever
run. This turned the "pre-commit checks" job red on every push regardless of
the diff.
Replace the brew tap install with `go install
github.com/norwoodj/helm-docs/cmd/helm-docs@v1.14.2`, matching apache/superset
upstream and keeping the binary version aligned with the helm-docs pre-commit
hook rev in .pre-commit-config.yaml.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three link sites render plain anchors (Typography.Link href=...) rather than
router <Link to=...>, so they bypass the <Router basename> that prefixes the
rest of the app and produce broken links under a SUPERSET_APP_ROOT
subdirectory deployment:
- the delete-dataset modal's "Affected Dashboards" / "Affected Charts" lists
- the tag list page's dashboard, chart and query rows
- an empty dashboard tab's "create a new chart" link
Add a prefixAppRoot helper to pathUtils and apply it at those sites. It cannot
reuse ensureAppRoot: that helper skips paths that already start with the
application root, and the dashboard route is itself /superset/dashboard/<id>/,
so with an application root of /superset it no-ops and the link stays broken.
prefixAppRoot always prefixes, which is what these router-relative paths need,
and it reproduces exactly what <Link to={url}> already renders via the router
basename on the dashboard and chart list pages. Absolute and protocol-relative
URLs still pass through untouched.
Cover each site with subdirectory regression tests, including the colliding
/superset root, plus unit tests for the helper.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit bd9ba24266)
[6.0 adaptation] Production schema aliases (chart/dashboard/dataset schemas.py)
applied to the 6.0 baseline. Two files needed adaptation because 6.0 predates
later MCP refactors:
- chart/schemas.py: kept the 6.0 base classes and added only
`model_config = ConfigDict(populate_by_name=True)` to GenerateExploreLinkRequest
and UpdateChartPreviewRequest. Dropped upstream's ChartRequestNormalizerMixin
base (absent on 6.0 — would be F821); the model_config achieves the same
populate-by-name behavior the aliases require.
- test_dashboard_schemas.py: kept TestRequestSchemaAliasChoices (exercises
GetDashboardInfoRequest / ListDashboardsRequest / AddChartToDashboardRequest —
all present on 6.0). Dropped upstream's TestDuplicateDashboardResponse (the
Duplicate Dashboard feature is absent on 6.0).
dashboard/dataset schemas.py, chart/dataset tests, and the new dataset test
file applied clean. pytest: 184 passed (42 alias/canonical-resolution cases)
across all three schema test files.
Co-authored-by: Enzo Martellucci <52219496+EnxDev@users.noreply.github.com>
(cherry picked from commit 76bb5f8e69)
[6.0 adaptation] Production sources (reducers/nativeFilters.ts, util/getRelatedCharts.ts,
actions/nativeFilters.ts, actions/chartCustomizationActions.ts) applied clean. Only the two
test files were ported to the 6.0 baseline:
- reducers/nativeFilters.test.ts: dropped 6.0's stale SET_NATIVE_FILTERS_CONFIG_COMPLETE
tests that asserted the pre-fix "backend response is the source of truth / drop-on-omit"
behavior; those directly contradict the landed merge-based reducer (which now preserves
untouched filters and only removes ids in action.deletedIds). Kept #42032's canonical
new-behavior set: removes deleted / removes all when all ids deleted / preserves untouched
on omit / mixed Filter+ChartCustomization / adds+removes / merges+deletes.
- util/getRelatedCharts.test.ts: kept the undefined-filter guard test; excluded two
master-baseline DatasourceType.SemanticView cases (SemanticView is absent on 6.0).
jest: 23/23 green across both files (nativeFilters.test.ts + getRelatedCharts.test.ts).
Manual port of apache/superset#39917 (commit 85935b0b) onto 6.0-release.
A clean cherry-pick does not apply because mcp_service/auth.py has diverged
structurally on this branch, but the vulnerable code path is present verbatim:
sync_wrapper calls db.session.remove() before user resolution on reused
thread-pool threads. If the thread-local DBAPI connection died between
requests (RDS SSL idle-timeout / max-connection-age), the implicit rollback
raises a DBAPIError and crashes the tool call.
Wrap the pre-call remove in _remove_session_safe(), which catches DBAPIError,
invalidates the dead connection so the pool discards it, and retries remove()
so the tool proceeds on a fresh connection. Ports the accompanying regression
test byte-for-byte behaviorally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>