Handle deleted GitHub issues (410 error) gracefully (#13217)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Rohit Malhotra
2026-03-04 15:50:37 -05:00
committed by GitHub
parent 15e9435b35
commit bf769d1744
2 changed files with 50 additions and 11 deletions

View File

@@ -3,7 +3,7 @@ from typing import Any
from uuid import UUID from uuid import UUID
import httpx import httpx
from github import Auth, Github, GithubIntegration from github import Auth, Github, GithubException, GithubIntegration
from integrations.utils import get_summary_instruction from integrations.utils import get_summary_instruction
from integrations.v1_utils import handle_callback_error from integrations.v1_utils import handle_callback_error
from pydantic import Field from pydantic import Field
@@ -132,19 +132,30 @@ class GithubV1CallbackProcessor(EventCallbackProcessor):
full_repo_name = self.github_view_data['full_repo_name'] full_repo_name = self.github_view_data['full_repo_name']
issue_number = self.github_view_data['issue_number'] issue_number = self.github_view_data['issue_number']
if self.inline_pr_comment: try:
if self.inline_pr_comment:
with Github(auth=Auth.Token(installation_token)) as github_client:
repo = github_client.get_repo(full_repo_name)
pr = repo.get_pull(issue_number)
pr.create_review_comment_reply(
comment_id=self.github_view_data.get('comment_id', ''),
body=summary,
)
return
with Github(auth=Auth.Token(installation_token)) as github_client: with Github(auth=Auth.Token(installation_token)) as github_client:
repo = github_client.get_repo(full_repo_name) repo = github_client.get_repo(full_repo_name)
pr = repo.get_pull(issue_number) issue = repo.get_issue(number=issue_number)
pr.create_review_comment_reply( issue.create_comment(summary)
comment_id=self.github_view_data.get('comment_id', ''), body=summary except GithubException as e:
if e.status == 410:
_logger.info(
'[GitHub V1] Issue/PR %s#%s was deleted, skipping summary post',
full_repo_name,
issue_number,
) )
return else:
raise
with Github(auth=Auth.Token(installation_token)) as github_client:
repo = github_client.get_repo(full_repo_name)
issue = repo.get_issue(number=issue_number)
issue.create_comment(summary)
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Agent / sandbox helpers # Agent / sandbox helpers

View File

@@ -15,6 +15,7 @@ from uuid import uuid4
import httpx import httpx
import pytest import pytest
from github import GithubException
from integrations.github.github_v1_callback_processor import ( from integrations.github.github_v1_callback_processor import (
GithubV1CallbackProcessor, GithubV1CallbackProcessor,
) )
@@ -734,6 +735,33 @@ class TestGithubV1CallbackProcessor:
with pytest.raises(RuntimeError, match='Missing GitHub credentials'): with pytest.raises(RuntimeError, match='Missing GitHub credentials'):
await github_callback_processor._post_summary_to_github('Test summary') await github_callback_processor._post_summary_to_github('Test summary')
@patch('integrations.github.github_v1_callback_processor.Auth')
@patch('integrations.github.github_v1_callback_processor.Github')
async def test_post_summary_to_github_deleted_issue_does_not_raise(
self, mock_github, mock_auth, github_callback_processor
):
"""Test that 410 errors (deleted issues) are handled gracefully without raising."""
mock_github_client = MagicMock()
mock_repo = MagicMock()
mock_repo.get_issue.side_effect = GithubException(
status=410,
data={'message': 'This issue was deleted'},
headers={},
)
mock_github_client.get_repo.return_value = mock_repo
mock_github.return_value.__enter__.return_value = mock_github_client
mock_token_auth = MagicMock()
mock_auth.Token.return_value = mock_token_auth
with patch.object(
github_callback_processor,
'_get_installation_access_token',
return_value='test_token',
):
# Should not raise - 410 errors are handled gracefully
await github_callback_processor._post_summary_to_github('Test summary')
@patch( @patch(
'integrations.github.github_v1_callback_processor.GITHUB_APP_CLIENT_ID', 'integrations.github.github_v1_callback_processor.GITHUB_APP_CLIENT_ID',
'test_client_id', 'test_client_id',