Skip to content

[9.4] [GitHub] Propagate fetch errors instead of swallowing them (#4119) - #4135

Merged
Jan-Kazlouski-elastic merged 1 commit into
9.4from
backport/9.4/pr-4119
Jul 7, 2026
Merged

Jan-Kazlouski-elastic merged 1 commit into
9.4from
backport/9.4/pr-4119

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Backports the following commits to 9.4:

## Summary

Fixes the GitHub connector silently swallowing errors during sync.
Previously each fetch method wrapped its whole body in `try/except
Exception: log warning`, so a sync could "succeed" while syncing nothing
(e.g. if no issues could be fetched at all). This implements the
two-tier error handling requested in the issue, removes the broad
exception handling, and hardens null-handling of GraphQL responses.

Part of #2393, closes #2395.

## Changes

### Two-tier error handling (`datasource.py`)
- **Page/API-level failures propagate** out of `_fetch_repos` /
`_fetch_pull_requests` / `_fetch_issues` / `_fetch_files` /
`_fetch_files_by_path`, so the sync fails when data genuinely can't be
fetched.
- **Per-document enrichment failures are WARN-logged and skipped** via
narrow guards that catch only `gidgethub.GitHubException`, so a single
bad issue/PR/file no longer aborts the whole sync.

### Transient rate limiting
- `_put_to_sleep` now only sleeps; its callers re-raise a dedicated
`RateLimitingError`, which is not in `skipped_exceptions`, so the
existing `@retryable` layer retries it.

### No more bare `except Exception`
- Replaced across the `github/` package with `gidgethub.GitHubException`
(plus the connector's own `UnauthorizedException` / `ForbiddenException`
in log-and-reraise spots like `ping` and
`_get_invalid_repos_for_personal_access_token`).

### Null-safe GraphQL response handling
- GitHub can return `null` for connection fields (`reviews`, `comments`,
`labels`, `assignees`, `reviewRequests`, `tree`, edge nodes). The old
`x.get("key", {}).get(...)` pattern crashes with
`AttributeError`/`TypeError` when the key is present but its value is
`null` (`.get()` only applies the default when the key is absent).
Switched the fetch/prepare helpers to the `... or {}` / `... or []`
idiom so a single such document can no longer abort the sync.

### Tests
- Added coverage for propagation vs. per-item skip for each fetch
method, `RateLimitingError` propagation, and regression tests for
issues/PRs with null connection fields.
- Fixed a latent test-isolation bug where shared mock fixtures were
mutated across tests and the resulting error was hidden by the old
catch-all (now `deepcopy`).

## Acceptance criteria

- [x] GitHub connector fails syncs if no issues can be synced
(page-level errors propagate)
- [x] GitHub connector attempts retries for errors that look transient
(`@retryable` + `RateLimitingError`)
- [x] Errors with limited scope (single documents / edge cases) are
moved past with WARN logging

## Test plan

- `pytest tests/sources/test_github.py` — 121 passed
- Passes across multiple random orderings (`-p randomly` seeds
1/2/42/100/777)
- `ruff check` clean on changed files

## Notes for reviewers

- The per-item guard wraps `_fetch_remaining_fields`, which itself makes
paginated calls. The design assumes systemic backend failures surface on
the initial page fetch (which propagates and fails the sync). If a
systemic error only manifested during per-item enrichment, it could be
WARN-skipped for every document without failing the sync. Happy to add
per-repo "synced at least one" tracking if we want a hard guarantee.
- `raise Exception(msg)` remains for non-rate-limited GraphQL
`QueryError`s in `graphql()`; left as-is as a possible small follow-up.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
@Jan-Kazlouski-elastic
Jan-Kazlouski-elastic merged commit 111c412 into 9.4 Jul 7, 2026
2 checks passed
@Jan-Kazlouski-elastic
Jan-Kazlouski-elastic deleted the backport/9.4/pr-4119 branch July 7, 2026 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants