mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-10-22 19:32:55 -05:00
## Description
Backend PR for the connector checks redesign, stacked on #16199. HubSpot
follows the design's rows, copy and states.
**HubSpot**
- **Rows:**
- The 9 checks are the design's 9 rows, with its names: "Sign in to
HubSpot", "Read tickets", "Read companies", "Read deals", "Read
contacts", "List linked records", "Sample notes", "List users" and "Read
record viewers".
- Dependencies follow the design's run order, with one change. "List
linked records" and "Sample notes" run after the sign-in, not after the
four read checks. A dependency that finds nothing to test stops the
checks after it. Many portals have no tickets, so "No tickets in
HubSpot" would stop both checks, but they can test a record of another
type. The two checks sample the first type that lists a record, and they
leave out a denied type: its read check reports it.
- **Copy:**
- Every failure gives the design's line and description.
- A denial names the private app scope that HubSpot needs, e.g. "In
HubSpot, add `crm.objects.deals.read` to the private app's scopes."
- Passing checks give what they found: "Signed in to account
{portal_id}", "Found {n} tickets" (the count from the Search API),
"Listed contacts linked to tickets", "Read a note linked to a ticket",
"{n} users found", "{n} users can view a sample ticket". Singular and
plural forms are correct ("Found 1 company").
- **Honest passes.** These checks passed while testing nothing:
- A type with no records is now Skipped ("No tickets in HubSpot").
- When no selected type has a record, the connector would index nothing.
The first read check now fails ("No records in the selected types").
This blocks Create.
- No record in scope is now Skipped for "List linked records", "Sample
notes" and "Read record viewers" ("No records in scope").
- A sample record without notes is now Incomplete ("No notes found to
test").
- No listed user is now Incomplete ("No users found to test").
**Fixes from the design's review**
- **Rate limits.** After the rate limiter's 5 retries, a check raises
`RateLimitedValidationError`, which stops the run. Before, the limit was
an unexpected error.
- **Sign-in.** It now reports a missing token ("Account has no API
token"), an unreachable HubSpot ("Cannot reach HubSpot") and a timeout
("Sign-in timed out"). On a form run, an unreachable HubSpot or a
timeout fails sign-in. A 5xx or an answer that is not JSON is
"Unexpected response from HubSpot" (Incomplete).
- **Error Details.** `HubSpotApiError` is a `SourceApiError`. The
gateway adds the method, the URL and HubSpot's error body, for SDK and
REST calls, so Error Details show them.
- **Connection errors.** The gateway raises `HubSpotConnectionError`
(with `timed_out`) for a connection failure or a timeout, from the SDK
and from REST calls. The checks cannot import `requests` (the SDK import
fence).
- **Permission sync validation.** `validate_hubspot_perm_sync` accepts a
portal with no records. Before, the viewers check passed silently there;
now it raises `NothingToCheckError`, which would pause the connector.
**Not in this PR:**
- `validates_binding` on "Sign in to HubSpot". The design says sign-in
unlocks the form, but HubSpot's config has no credential-bound fields,
and the framework requires a binding class for a binding check
(`test_binding_checks_require_only_bound_fields`). GitHub and Google
Drive also leave it out.
- The design's HubSpot text for the 10-minute hang guard ("The check
stopped after 10 minutes without an answer from HubSpot."). The runner
writes this row text for every source. A per-source text needs a
framework change.
## How Has This Been Tested?
- New unit tests (`test_hubspot_check_row_text.py`): the sign-in lines,
the form-run policy (unreachable and timeout), the rate-limit stop, the
dependency stops, Error Details, the empty-type and empty-scope states,
the samples' Skipped and Incomplete states, and that "List linked
records" runs past an empty type.
- New gateway tests: SDK and REST errors carry the request and body; a
connection failure says whether it timed out; a search keeps its match
count.
- Existing HubSpot check tests updated to the new states.
- Connector, server and EE unit tests: 5519 passed, 25 skipped, 1
failed. The failed test is a web connector test
(`test_browser_lifecycle.py`). It also fails without this change. `ty`
and pre-commit are clean.
- HubSpot has no daily live capability-check test, so there is nothing
to update there.
## Additional Options
- [ ] [Optional] Please cherry-pick this PR to the latest release
version.
- [x] [Optional] Override Linear Check
---
_Generated by [Claude
Code](https://claude.ai/code/session_01KFMazQbuG8ui3jxBxm47sC)_
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Rewrites the HubSpot capability checks to follow the checks design: nine
rows with the design's names, run order, copy, and outcome states.
Checks now report what they tested and what they found instead of
passing silently.
- "List linked records" and "Sample notes" run after sign-in only, so an
empty or denied type no longer stops them.
- Read checks report Search API counts with singular and plural forms; a
full users page reports a "100+" lower bound.
- Empty types are Skipped, a record without notes or no listed user is
Incomplete, and a portal with no records of any selected type fails the
first read check to block Create.
- Rate limits stop the run after retries with a clear message; sign-in
reports missing tokens, unreachable HubSpot, and timeouts, failing a
form run on the latter two.
- HubSpot API errors now carry the request method, URL, and response
body so Error Details show them; connection failures raise a dedicated
`HubSpotConnectionError`.
- Permission sync validation accepts a portal with no records instead of
raising.
- Row copy uses the shared `CheckRowText` model, and the check tests
share a helpers module.
<sup>Written for commit a938308bab.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/onyx-dot-app/onyx/pull/16200?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/onyx-dot-app/onyx/16200?returnTo=https%3A%2F%2Fgithub.com%2Fonyx-dot-app%2Fonyx%2Fpull%2F16200&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* HubSpot connection checks now distinguish common issues, including
invalid credentials, missing permissions, rate limits, and connectivity
problems.
* Permission checks provide clearer results when selected data is empty
or inaccessible, and can continue checking other readable record types.
* User checks report the number of users found, while record-viewer
checks report viewer counts when a sample is available.
* HubSpot requests handle timeouts and connection failures more
consistently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>