Skip to content

Commit

Permalink
Merge pull request #4591 from opensafely-core/Jongmassey/Project-page…
Browse files Browse the repository at this point in the history
…-doesnt-load-when-GitHub-API-is-unreachable

Project page doesnt load when GitHub api is unreachable
  • Loading branch information
Jongmassey authored Sep 25, 2024
2 parents abfbd82 + 6661715 commit d8b872b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
11 changes: 7 additions & 4 deletions jobserver/views/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def get_repo(repo, ctx):
is_private = self.get_github_api().get_repo_is_private(
repo.owner, repo.name
)
except requests.HTTPError:
except (requests.HTTPError, requests.Timeout, requests.ConnectionError):
is_private = None
span = trace.get_current_span()
span.set_attribute("repo_owner", repo.owner)
Expand All @@ -187,9 +187,12 @@ def get_repo(repo, ctx):
}

# use the threadpool to parallelise the repo requests
yield from repo_thread_pool.map(
get_repo, repos, itertools.repeat(ctx), timeout=30
)
try:
yield from repo_thread_pool.map(
get_repo, repos, itertools.repeat(ctx), timeout=30
)
except TimeoutError:
yield {"name": "GitHub API Unavailable", "is_private": None, "url": ""}


class ProjectEdit(UpdateView):
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/jobserver/views/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,37 @@ def get_repo_is_private(self, *args):
assert "Public" not in response.rendered_content


def test_projectdetail_with_timed_out_github(rf):
project = ProjectFactory(org=OrgFactory())
WorkspaceFactory(
project=project, repo=RepoFactory(url="https://github.com/owner/repo")
)
WorkspaceFactory(project=project, repo=RepoFactory(url="/path/on/disk/to/repo"))

request = rf.get("/")
request.user = UserFactory()

class BrokenGitHubAPI:
def get_repo_is_private(self, *args):
raise TimeoutError

response = ProjectDetail.as_view(get_github_api=BrokenGitHubAPI)(
request, project_slug=project.slug
)

assert response.status_code == 200

# check there is no public/private badge when GitHub returns an
# unsuccessful response
assert not response.context_data["public_repos"]
assert response.context_data["private_repos"][0] == {
"name": "GitHub API Unavailable",
"is_private": None,
"url": "",
}
assert "Public" not in response.rendered_content


def test_projectdetail_with_no_jobs(rf):
project = ProjectFactory()

Expand Down

0 comments on commit d8b872b

Please sign in to comment.