feat(connectors): checks report timeouts with their own kind and row text
Merged
EV
2d ago+515+515+012345678901234567890123456789-54-54-01234567890123456789
Description
Backend PR for the connector checks redesign, stacked on #16210. It does three things in the check framework and makes a small change to each connector's checks.
1. A typed timeout error (exceptions.py, capability_checks/models.py)
- New
TimedOutValidationError. It subclassesUnreachableValidationError, so code that catches an unreachable source also catches a timeout. check_error_kindmaps it toerror_kind=timeout. The kind has the policy ofunreachable. It is Failed on a form run when the check setsfails_when_unreachable=True, and Incomplete in all other cases. A result of this kind keeps a Stack Trace.- These gateways already tell a timeout from a refused connection. Their checks now raise the new error:
- Jira:
JiraTimeoutErrorat sign-in and in the other checks. Before, #16207 usedUnreachableValidationError, because this class did not exist. - HubSpot:
HubSpotConnectionError.timed_outat sign-in and in the other checks. - Notion:
NotionApiError.timed_outat sign-in and in the other checks. - Linear:
LinearUnreachableError.timed_outat sign-in and in the other checks. - GitHub and Confluence sign-in: they caught
requests.Timeoutandrequests.ConnectionErrortogether. The checks now catchrequests.Timeoutfirst and show the design's "Sign-in timed out" row. A refused connection still shows "Cannot reach …".
- Jira:
2. Timeout text for each check (CapabilityCheck.timeout_text)
- Before, the runner's hang guard wrote the same "Timed out" text for every check of every source. A check can now set
timeout_text=CheckRowText(summary=..., description=...). The hang guard uses this text. With notimeout_text, the runner's default text stays. sign_in_timeout_text("{Source}")gives the design's sign-in text: "Sign-in timed out" / "{Source} did not answer the sign-in in time. Re-run, or check that {Source} is reachable from Onyx."- Each connector's check base class sets the shared "Timed out" text of its source (design
sources[].shared), and its sign-in check sets the sign-in text. This applies to all 11 sources with named checks, and to their permission-sync checks. - A
{time_limit}placeholder in a description shows the hang guard's real time limit, for example "10 minutes". The design writes "10 minutes", but a form run caps the hang guard at 5 minutes, and the Slack channel check uses 30 minutes. - The error's own text is still first.
timeout_textis used only when the hang guard stops the check.
3. A cycle guard in _http_detail
_http_detailfollows an error's__cause__chain to find the HTTP response. A cycle in that chain made the run loop forever. The function now keeps a set of the errors it saw (byid), asgeneric_row._http_statusdoes.
Changes from the design
- Microsoft (SharePoint, OneDrive, Outlook) request timeouts stay
unreachable. The Graph error mapper (_is_transport_failure) puts a timeout and a refused connection in one group. A split needs new copy for every Graph row. The hang-guard text for these sources does follow the design. - Slack sign-in request timeouts stay
unreachablefor the same reason: the check catchesURLErrorandConnectionError, and does not tell a timeout apart. A rawTimeoutErroralready goes to the hang-guard path, which now shows the Slack sign-in text. - HubSpot request timeouts after sign-in: the design has no line for them. I used the same text as the Notion PR: "Timed out" / "HubSpot did not answer the request in time. Re-run the checks." Before, these timeouts showed "Cannot reach HubSpot".
- The generic row (
generic_row.py) does not change. The design has no timeout row for it.
How Has This Been Tested?
- New unit tests (
capability_checks/test_check_timeout_rows.py): the kind and status ofTimedOutValidationErroron form and other runs, its Stack Trace, the hang guard with and withouttimeout_text, the error's own text first, the{time_limit}words, the timeout text of every source's checks in the registry, and the cycle guard (with a cycle before and after aSourceApiError). - Updated connector tests: Jira, HubSpot, Notion, Linear, GitHub and Confluence now check
error_kind=timeoutfor a request timeout. New tests cover the GitHub and Confluence sign-in timeout and a HubSpot timeout after sign-in. - Connector and server unit tests: 4629 passed, 24 skipped, 1 failed. The failure (
web/test_browser_lifecycle.py::test_download_is_not_retried_and_does_not_relaunch_browser) also fails without this change. This PR does not change the web connector. - Pre-commit is clean (golangci-lint skipped: the hook cannot install here).
Additional Options
- [Optional] Please cherry-pick this PR to the latest release version.
- [Optional] Override Linear Check
Generated by Claude Code
Summary by cubic
Connector checks now distinguish a request timeout from an unreachable source, and the hang guard shows each source's own timeout row text instead of a generic line.
- Adds
TimedOutValidationErrorwitherror_kind=timeout; it inherits the unreachable policy, so a form run fails when the check setsfails_when_unreachable, and other runs stay Incomplete. - Jira, HubSpot, Notion, and Linear raise it for a timed-out request; GitHub and Confluence raise it for a sign-in timeout, now catching
requests.Timeoutbefore connection errors. - Confluence's user-name lookup now reports kind
timeouttoo, instead ofunreachable. - Checks can set
timeout_text, which the hang guard shows with the real time limit; sign-in checks use "Sign-in timed out" text. All 11 named-check sources set their design text. _http_detailnow guards against a cycle in an error's__cause__chain, which previously looped forever.
Summary by CodeRabbit
-
Bug Fixes
- Capability checks now distinguish timeouts from unreachable-source errors.
- Timeout results display clearer, connector-specific messages, including sign-in guidance.
- Timeout messages show the applicable time limit and preserve detailed error information.
- Timeout handling is now more consistent across supported connectors, including Confluence, GitHub, Jira, Linear, Notion, and others.
-
Tests
- Added coverage for timeout classification, customized messages, time-limit formatting, and error details.