apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
61.58k stars 13.44k forks source link

Report fails to generate if dashboard doesn't contain a chart #29629

Open oscep opened 1 month ago

oscep commented 1 month ago

Bug description

Superset cannot create a report for a dashboard without a chart element because the Selenium code involved waits for at least one chart element to render. A timeout occurs without a chart element present (see stack trace below).

This leads to an error message in the execution log which doesn't provide any meaningful information:

Screenshot 2024-07-18 at 10 00 03

We would suggest to either take a screenshot without chart elements present or to include a meaningful hint in the error message. Feel free to propose different solutions :-)

How to reproduce the bug

  1. Create a Superset dashboard with a text layout element but no chart
  2. Enable and configure Alerts & Reports for your Superset instance
  3. Schedule a report for the dashboard created above
  4. Access the execution log of the report.

Screenshots/recordings

No response

Superset version

4.0.2

Python version

3.10

Node version

18 or greater

Browser

Chrome

Additional context

Selenium timed out waiting for chart containers to draw at url http://superset.data:30080/superset/dashboard/914cb113-ac4a-4ba4-a46e-8f05e517691b/?force=false&standalone=3
Traceback (most recent call last):
  File "/app/superset/utils/webdriver.py", line 378, in get_screenshot
    WebDriverWait(driver, self._screenshot_locate_wait).until(
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/support/wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

Checklist

dosubot[bot] commented 1 month ago

Hello @oscep! I'm here to help you with any bugs, questions, or contributions you have for the repository. Let's work together to solve any issues you're facing.

To address the issue of generating reports for dashboards without chart elements, you can use the force_screenshot option. This option ensures that a screenshot is taken even if the dashboard does not contain any chart elements. Here is the relevant code snippet:

const shouldEnableForceScreenshot = contentType === 'chart' && !isReport;
const data: any = {
  ...currentAlert,
  type: isReport ? 'Report' : 'Alert',
  force_screenshot: shouldEnableForceScreenshot || forceScreenshot,
  validator_type: conditionNotNull ? 'not null' : 'operator',
  validator_config_json: conditionNotNull
    ? {}
    : currentAlert?.validator_config_json,
  chart: contentType === 'chart' ? currentAlert?.chart?.value : null,
  dashboard:
    contentType === 'dashboard' ? currentAlert?.dashboard?.value : null,
  custom_width: isScreenshot ? currentAlert?.custom_width : undefined,
  database: currentAlert?.database?.value,
  owners: (currentAlert?.owners || []).map(
    owner => (owner as MetaObject).value || owner.id,
  ),
  recipients,
  report_format: reportFormat || DEFAULT_NOTIFICATION_FORMAT,
};

This approach ensures that the alert or report will still function correctly even if the dashboard lacks chart elements by forcing a screenshot [1].

Additionally, to provide more meaningful error messages, you can customize the error handling in the report scheduling system. For example, you can modify the string passed to the custom exceptions to include more context, such as the report name:

raise ReportScheduleScreenshotFailedError(
    f"Failed taking a screenshot for report {self._report_schedule.name}: {str(ex)}"
) from ex

This would make the error messages more informative and helpful for debugging [2][3].

To continue talking to Dosu, mention @dosu.