mirror of
https://github.com/apache/superset.git
synced 2026-07-26 00:22:31 +00:00
fix(reports): don't let PlaywrightTimeout=Exception fallback swallow unrelated errors
CI failures on this branch traced to two issues: 1. take_tiled_screenshot()'s outer `except PlaywrightTimeout: raise` / `except Exception: return None` pair assumed PlaywrightTimeout is always distinguishable from a generic Exception. It isn't: when the playwright package isn't installed, `PlaywrightTimeout = Exception` (see the try/except ImportError above the function). In that case *any* exception -- not just our own deliberate per-tile readiness-timeout raise -- matched `except PlaywrightTimeout` first and incorrectly propagated instead of degrading to `None` like every other unexpected error (e.g. the initial dashboard element never appearing). This is exactly what unit-tests hit in CI (no playwright installed there), turning `test_element_not_found_returns_none` and `test_exception_handling_*` into uncaught-exception failures. Fixed by tracking the "this is our own readiness timeout" case with an explicit boolean flag set right before the inner `raise`, instead of relying on exception-type dispatch that can't tell the two cases apart when the import fallback is active. 2. `execute.py` now always passes `log_context=...` to `screenshot.get_screenshot(...)`. One integration test (`test_email_chart_report_schedule_alpha_owner`) mocks `ChartScreenshot.get_screenshot` with a side_effect function whose signature only accepted `user`, so the new kwarg raised a TypeError, caught by execute.py's own error handling and reported as a ReportScheduleScreenshotFailedError in test-mysql/postgres/sqlite. Fixed by accepting the new `log_context` keyword in that test's side_effect signature. Confirmed this was the only such call site in the test suite (all others use plain `.return_value`/exception-instance side effects, which don't care about the new kwarg). Verified locally with and without playwright installed, matching both conditions CI exercises. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -184,6 +184,16 @@ def take_tiled_screenshot(
|
||||
Combined screenshot bytes or None if failed
|
||||
"""
|
||||
context_suffix = f" [{log_context}]" if log_context else ""
|
||||
# Set right before re-raising the per-tile readiness timeout below, and
|
||||
# checked in the except block at the bottom of this function. Deciding
|
||||
# whether to propagate via `isinstance(e, PlaywrightTimeout)` would be
|
||||
# unreliable: when the playwright package isn't installed,
|
||||
# `PlaywrightTimeout` is aliased to the bare `Exception` class (see the
|
||||
# try/except ImportError above this function), which would make *any*
|
||||
# exception -- not just our own deliberate readiness-timeout raise --
|
||||
# match `except PlaywrightTimeout` and incorrectly propagate instead of
|
||||
# degrading to `None` like every other unexpected error in this function.
|
||||
readiness_timeout = False
|
||||
try:
|
||||
# Get the target element
|
||||
element = page.locator(f".{element_name}")
|
||||
@@ -263,6 +273,7 @@ def take_tiled_screenshot(
|
||||
context_suffix,
|
||||
unready_chart_holders,
|
||||
)
|
||||
readiness_timeout = True
|
||||
raise
|
||||
else:
|
||||
elapsed = time.monotonic() - tile_wait_start
|
||||
@@ -328,13 +339,15 @@ def take_tiled_screenshot(
|
||||
|
||||
return combined_screenshot
|
||||
|
||||
except PlaywrightTimeout:
|
||||
# Let per-tile readiness timeouts propagate so the caller fails the
|
||||
# report instead of silently falling back to a degraded screenshot.
|
||||
raise
|
||||
except Exception as e:
|
||||
# Unlike the readiness-timeout warning above, this is a genuine
|
||||
# system-level fault (unexpected error, not a customer chart taking
|
||||
# too long to load), so it stays at ERROR/exception level.
|
||||
if readiness_timeout:
|
||||
# Let the per-tile readiness timeout propagate so the caller
|
||||
# fails the report instead of silently falling back to a
|
||||
# degraded screenshot -- already logged as a WARNING above.
|
||||
raise
|
||||
# Any other exception is a genuine system-level fault (or a setup
|
||||
# failure unrelated to chart readiness, e.g. the dashboard element
|
||||
# itself never appearing), not a customer chart taking too long to
|
||||
# load, so it stays at ERROR/exception level.
|
||||
logger.exception("Tiled screenshot failed: %s%s", e, context_suffix)
|
||||
return None
|
||||
|
||||
@@ -826,7 +826,9 @@ def test_email_chart_report_schedule_alpha_owner(
|
||||
# setup screenshot mock
|
||||
username = ""
|
||||
|
||||
def _screenshot_side_effect(user: User) -> Optional[bytes]:
|
||||
def _screenshot_side_effect(
|
||||
user: User, log_context: Optional[str] = None
|
||||
) -> Optional[bytes]:
|
||||
nonlocal username
|
||||
username = user.username
|
||||
|
||||
|
||||
Reference in New Issue
Block a user