99import logging
1010from datetime import datetime
1111from typing import Callable , ParamSpec , TypeVar
12- from urllib .error import HTTPError
12+ from urllib .error import HTTPError , URLError
1313
1414import requests
1515
3939
4040logger = logging .getLogger (__name__ )
4141
42+ TIMEOUT_IN_SECS = 60
43+
4244
4345class GithubRunnerNotFoundError (Exception ):
4446 """Represents an error when the runner could not be found on GitHub."""
@@ -77,6 +79,7 @@ def wrapper(*args: ParamT.args, **kwargs: ParamT.kwargs) -> ReturnT:
7779 """
7880 try :
7981 return func (* args , ** kwargs )
82+ # The ghapi module uses urllib. The HTTPError and URLError are urllib exceptions.
8083 except HTTPError as exc :
8184 if exc .code in (401 , 403 ):
8285 if exc .code == 401 :
@@ -86,9 +89,15 @@ def wrapper(*args: ParamT.args, **kwargs: ParamT.kwargs) -> ReturnT:
8689 raise TokenError (msg ) from exc
8790 logger .warning ("Error in GitHub request: %s" , exc )
8891 raise PlatformApiError from exc
92+ except URLError as exc :
93+ logger .warning ("General error in GitHub request: %s" , exc )
94+ raise PlatformApiError from exc
8995 except RequestException as exc :
9096 logger .warning ("Error in GitHub request: %s" , exc )
9197 raise PlatformApiError from exc
98+ except TimeoutError as exc :
99+ logger .warning ("Timeout in GitHub request: %s" , exc )
100+ raise PlatformApiError from exc
92101
93102 return wrapper
94103
@@ -124,11 +133,11 @@ def get_runner(self, path: GitHubPath, prefix: str, runner_id: int) -> SelfHoste
124133 try :
125134 if isinstance (path , GitHubRepo ):
126135 raw_runner = self ._client .actions .get_self_hosted_runner_for_repo (
127- path .owner , path .repo , runner_id
136+ path .owner , path .repo , runner_id , timeout = TIMEOUT_IN_SECS
128137 )
129138 else :
130139 raw_runner = self ._client .actions .get_self_hosted_runner_for_org (
131- path .org , runner_id
140+ path .org , runner_id , timeout = TIMEOUT_IN_SECS
132141 )
133142 except HTTP404NotFoundError as err :
134143 raise GithubRunnerNotFoundError from err
@@ -164,6 +173,7 @@ def list_runners(self, path: GitHubPath, prefix: str) -> list[SelfHostedRunner]:
164173 owner = path .owner ,
165174 repo = path .repo ,
166175 per_page = 100 ,
176+ timeout = TIMEOUT_IN_SECS ,
167177 )
168178 for item in page ["runners" ]
169179 ]
@@ -179,6 +189,7 @@ def list_runners(self, path: GitHubPath, prefix: str) -> list[SelfHostedRunner]:
179189 num_of_pages + 1 ,
180190 org = path .org ,
181191 per_page = 100 ,
192+ timeout = TIMEOUT_IN_SECS ,
182193 )
183194 for item in page ["runners" ]
184195 ]
@@ -217,6 +228,7 @@ def get_runner_registration_jittoken(
217228 name = instance_id .name ,
218229 runner_group_id = 1 ,
219230 labels = labels ,
231+ timeout = TIMEOUT_IN_SECS ,
220232 )
221233 elif isinstance (path , GitHubOrg ):
222234 # We cannot cache it in here, as we are running in a forked process.
@@ -227,6 +239,7 @@ def get_runner_registration_jittoken(
227239 name = instance_id .name ,
228240 runner_group_id = runner_group_id ,
229241 labels = labels ,
242+ timeout = TIMEOUT_IN_SECS ,
230243 )
231244 else :
232245 assert_never (token )
@@ -249,7 +262,7 @@ def _get_runner_group_id(self, org: GitHubOrg) -> int:
249262 "Authorization" : f"Bearer { self ._token } " ,
250263 "X-GitHub-Api-Version" : "2022-11-28" ,
251264 }
252- response = requests .get (url , headers = headers , timeout = 30 )
265+ response = requests .get (url , headers = headers , timeout = TIMEOUT_IN_SECS )
253266 response .raise_for_status ()
254267 data = response .json ()
255268 try :
@@ -282,11 +295,13 @@ def delete_runner(self, path: GitHubPath, runner_id: int) -> None:
282295 owner = path .owner ,
283296 repo = path .repo ,
284297 runner_id = runner_id ,
298+ timeout = TIMEOUT_IN_SECS ,
285299 )
286300 else :
287301 self ._client .actions .delete_self_hosted_runner_from_org (
288302 org = path .org ,
289303 runner_id = runner_id ,
304+ timeout = TIMEOUT_IN_SECS ,
290305 )
291306 # The function delete_self_hosted_runner fails in GitHub if the runner does not exist,
292307 # so we do not have to worry about that.
@@ -310,7 +325,12 @@ def get_job_info_by_runner_name(
310325 Returns:
311326 Job information.
312327 """
313- paged_kwargs = {"owner" : path .owner , "repo" : path .repo , "run_id" : workflow_run_id }
328+ paged_kwargs = {
329+ "owner" : path .owner ,
330+ "repo" : path .repo ,
331+ "run_id" : workflow_run_id ,
332+ "timeout" : 60 ,
333+ }
314334 try :
315335 for wf_run_page in paged (
316336 self ._client .actions .list_jobs_for_workflow_run , ** paged_kwargs
@@ -353,6 +373,7 @@ def get_job_info(self, path: GitHubRepo, job_id: str) -> JobInfo:
353373 owner = path .owner ,
354374 repo = path .repo ,
355375 job_id = job_id ,
376+ timeout = TIMEOUT_IN_SECS ,
356377 )
357378 except HTTPError as exc :
358379 if exc .code == 404 :
0 commit comments