mirror of
https://github.com/apache/superset.git
synced 2026-05-24 01:05:21 +00:00
The @backoff.on_exception decorator on SlackV2Notification.send() was configured to retry on SlackApiError, but the function's own try/except catches every SlackApiError and re-raises as NotificationUnprocessableException before the decorator can see it. As a result, no retries were happening — a single transient failure (rate limit, connection blip) would fail the report immediately, defeating the intent of the 5-attempt retry budget. Switch the decorator to retry on NotificationUnprocessableException, which is the exception type that send() actually raises for transient Slack failures (SlackApiError, SlackClientNotConnectedError, and the SlackClientError catch-all). Mirrors the working pattern already in webhook.py. Non-transient errors (NotificationParamException, NotificationMalformedException, NotificationAuthorizationException) still surface immediately — they aren't retryable and shouldn't be retried. Test changes: - Replaces the prior "locks in broken behavior" regression test with test_v2_send_retries_on_transient_slack_api_error asserting call_count == 5 - Adds test_v2_send_does_not_retry_param_errors verifying that BotUserAccessError → NotificationParamException is NOT retried (call_count == 1) - Adds an autouse fixture that patches backoff._sync.time.sleep so unit-test retries complete in milliseconds rather than the ~150s of real exponential backoff. Without this, the parametrized exception-mapping cases that map to NotificationUnprocessableException balloon the test runtime by ~75s The v1 SlackNotification has the same bug but is being deprecated in this release; not worth fixing there since v1's file_uploads endpoint is already dead at Slack's side and only the text-only chat_postMessage path still works. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>