eschutho opened a new pull request, #46063:
URL: https://github.com/apache/superset/pull/46063
### SUMMARY
A dashboard report or alert that has a tab or native filters, and **no valid
executor (run-as user)**, crashed with `'NoneType' object has no attribute
'is_anonymous'`, and the owner received no failure email. The same report
without a tab or filters failed cleanly with "Scheduled task executor not
found" and emailed the owner.
**Root cause:** when the executor can't be resolved, `get_executor_user`
returns `(None, None)` and the run proceeds with `g.user` unset. A plain report
fails later, in the screenshot step, with
`ReportScheduleExecutorNotFoundError`. A report with a tab or native filters
first builds its notification link: `_get_url` -> `_get_tab_url` ->
`CreateDashboardPermalinkCommand` -> `security_manager.raise_for_access` ->
`get_user_roles`, which reads `g.user.is_anonymous` on `None`.
`_raise_for_executor_dashboard_access` returned early for a missing user, so
nothing converted this into the executor error, and the failure-notification
path (`_get_failure_notification_url`, used by `send_error`) built the same
link and crashed too, so no email was sent.
**Changes** (all in `superset/commands/report/execute.py`; `get_user_roles`
in the security manager is untouched):
- `_raise_for_executor_dashboard_access` gets a `require_executor` flag.
With no user, when a permalink is about to be created (`_get_tab_url` passes
`True`), an unresolved executor now raises
`ReportScheduleExecutorNotFoundError`, the same error and handling as a plain
report (not retried, owner notified). The early return for an anonymous user is
unchanged.
- `_get_failure_notification_url` builds the stateful link as the resolved
executor (via `override_user`) when there is no user and the report has a
dashboard. This covers terminal-error handling that runs outside the executor's
user context. If the executor is missing or lacks access, it falls back to the
plain dashboard link so the owner still gets the email. Chart reports keep
their existing behaviour.
### TESTING INSTRUCTIONS
```
pytest tests/unit_tests/commands/report/execute_test.py \
tests/unit_tests/commands/report/executor_test.py
```
- `get_dashboard_urls` for a report with a tab / native filters and an
unresolved executor raises `ReportScheduleExecutorNotFoundError` instead of
`AttributeError`.
- `_get_failure_notification_url` falls back to the plain dashboard link
when the executor is missing, and builds the stateful link as the executor when
it is valid but no user is set.
- A state-level test runs `ReportNotTriggeredErrorState.next` for tab,
filters, plain-dashboard and chart reports with a missing executor and asserts
an ERROR log row, exactly one failure notification, no retry (even with
`retry_on_failure`), and the expected link.
- Anonymous-user behaviour is unchanged.
Five of the new tests fail on master. The others guard unchanged behaviour
(plain dashboard and chart reports, anonymous users, no retry).
Test limitation: the state-level test drives
`ReportNotTriggeredErrorState.next` rather than
`ReportScheduleStateMachine.run`, which is wrapped in a transaction.
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [ ] Required feature flags: `ALERT_REPORTS_FILTER`, `ALERT_REPORT_TABS`
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
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]