Skip to content

Conversation

@armenzg
Copy link
Member

@armenzg armenzg commented Feb 3, 2023

This fixes an issue where we would give up processing as soon as any Github API error would be returned (to the exception of some defined cases).

This also moves handling of errors to the caller in order to have a centralized processing.

This needs to land after #44110.

It seems that we raise unidentified API errors in get_tree. get_cached_repo_files does not catch it. The iteration of the repositories happens within the try/block, thus, failing to work as soon as one repo fails to process.

@armenzg armenzg self-assigned this Feb 3, 2023
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 3, 2023
@armenzg armenzg changed the title ref(dervied_code_mappings): Adjust handling of errors feat(derived_code_mappings): Do not abort if a repo fails to process Feb 3, 2023
@armenzg armenzg changed the title feat(derived_code_mappings): Do not abort if a repo fails to process fix(derived_code_mappings): Do not abort if a repo fails to process Feb 3, 2023
@armenzg armenzg force-pushed the armenzg/derived-code-mappings/catch-at-the-right-place branch from 67327c3 to 03bde1d Compare February 3, 2023 20:47
logger.warning(f"The Github App does not have access to {repo_full_name}.")
else:
# Raise it so we stop hammering the API
raise error
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In here we raise any non-identified error and this would cause the processing of all repos to abort.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use "Hide whitespace" this PR is easier to review.
image

Copy link
Member Author

@armenzg armenzg Feb 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this except block and letting _populate_trees handle it.

try:
# The Github API rate limit is reset every hour
# Spread the expiration of the cache of each repo across the day
trees[repo_full_name] = self._populate_tree(
repo_info, only_use_cache, (3600 * 24) + (3600 * (index % 24))
)
except ApiError as error:
process_error(error, extra)
except Exception:
# Report for investigatagiation but do not stop processing
logger.exception(

Copy link
Member Author

@armenzg armenzg Feb 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block basically comes from get_tree. We're now handling in here to allow keep moving forward with processing repositories rather than aborting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a call to _populate_tree raises an error, we will now report to Sentry and not abort the processing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now do a catch all in the new except block.

self.set_rate_limit(MINIMUM_REQUESTS + 50)
expected_trees = {
"Test-Organization/bar": RepoTree(Repo("Test-Organization/bar", "main"), []),
"Test-Organization/baz": RepoTree(Repo("Test-Organization/baz", "master"), []),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bar and baz return 4xx errors, thus, we do not store them in the trees object anymore.

def test_get_trees_for_org_works(self):
"""Fetch the tree representation of a repo"""
installation = self.get_installation_helper()
cache.clear()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that the next test would sometimes fail because the cache side effects of this test would affect the next.

I tried to add this as part of tearDown but it did not seem to matter. I will investigate on another occasion.

with patch("sentry.integrations.github.client.MINIMUM_REQUESTS", new=5, autospec=False):
# We start with one request left before reaching the minimum remaining requests floor
self.set_rate_limit(remaining=6)
assert cache.get(repos_key) is None
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good enough test to notice the cache cleared.

@armenzg armenzg marked this pull request as ready for review February 3, 2023 21:06
@armenzg armenzg requested review from a team February 3, 2023 21:06
Base automatically changed from armenzg/derived-code-mappings/prevent-api-rate-limit-exhaustion to master February 6, 2023 18:22
@armenzg armenzg marked this pull request as draft February 6, 2023 19:27
One of our customers is intermittently exhausting their rate limit, thus, affecting the commit_context tasks.

Changes included:

* get_repositories will not make API requests if the remaining requests is 200 or less. We will keep fetching repositories in the next hour when the limit is reset.
* Spread caching of repositories across 24 hours. This will make the task only use 1/24th of the required API requests.

Fixes (SENTRY-Y3M)[https://sentry.sentry.io/issues/3900033302/]
This fixes an issue where we would give up processing as soon as any Github API error would be returned (to the exception of some defined cases).

This also moves handling of errors to the caller in order to have a centralized processing.

It seems that [we raise unidentified API errors](https://github.com/getsentry/sentry/blob/d0252f70b97ceef909c86128566716255fab7eab/src/sentry/integrations/github/client.py#L124-L126) in get_tree. [get_cached_repo_files does not catch it](https://github.com/getsentry/sentry/blob/d0252f70b97ceef909c86128566716255fab7eab/src/sentry/integrations/github/client.py#L130-L161). [The iteration of the repositories happens within the try/block](https://github.com/getsentry/sentry/blob/d0252f70b97ceef909c86128566716255fab7eab/src/sentry/integrations/github/client.py#L170-L176), thus, failing to work as soon as one repo fails to process.
"""

def process_error(error: ApiError, extra: Dict[str, str]) -> None:
msg = "Continuing exectuion."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execution

This is easier to read if we just include it as part of the logger messages below since it's not conditional

@armenzg armenzg enabled auto-merge (squash) February 7, 2023 14:11
@armenzg armenzg merged commit e7544a3 into master Feb 7, 2023
@armenzg armenzg deleted the armenzg/derived-code-mappings/catch-at-the-right-place branch February 7, 2023 14:29
wmak pushed a commit that referenced this pull request Feb 16, 2023
…44126)

This fixes an issue where we would give up processing as soon as any Github API error would be returned (to the exception of some defined cases).

This also moves handling of errors to the caller in order to have a centralized processing.

It seems that [we raise unidentified API errors](https://github.com/getsentry/sentry/blob/d0252f70b97ceef909c86128566716255fab7eab/src/sentry/integrations/github/client.py#L124-L126)
in get_tree. [get_cached_repo_files does not catch it](https://github.com/getsentry/sentry/blob/d0252f70b97ceef909c86128566716255fab7eab/src/sentry/integrations/github/client.py#L130-L161). [The iteration of the repositories happens within the try/block](https://github.com/getsentry/sentry/blob/d0252f70b97ceef909c86128566716255fab7eab/src/sentry/integrations/github/client.py#L170-L176), thus, failing to work as soon as one repo fails to process.
@github-actions github-actions bot locked and limited conversation to collaborators Feb 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants