99'''
1010
1111import commonpy .exceptions
12- from commonpy .network_utils import network
12+ from commonpy .network_utils import net
13+ import contextlib
1314from functools import cache
1415import json
1516import os
@@ -108,8 +109,13 @@ def github_release(account_name, repo_name, tag_name):
108109 log ('getting GitHub data for release at ' + endpoint )
109110 result = _object_for_github (endpoint , GitHubRelease )
110111 if not result :
111- raise GitHubError (f'Can\' t get GitHub release data for { tag_name } in'
112- f' repository { repo_name } of account { account_name } ' )
112+ raise GitHubError (f'Failed to get GitHub release data for { tag_name } in'
113+ f' repository { repo_name } of account { account_name } .'
114+ ' This could be due to a number of causes. Please'
115+ ' check that the repository and release do exist, and'
116+ ' that the GitHub access token (if one is being used)'
117+ ' is configured with appropriate permissions to grant'
118+ ' access to the repository.' )
113119 return result
114120
115121
@@ -119,8 +125,13 @@ def github_repo(account_name, repo_name):
119125 log ('getting GitHub data for repo at ' + endpoint )
120126 result = _object_for_github (endpoint , GitHubRepo )
121127 if not result :
122- raise GitHubError ('Can\' t get GitHub repository data for'
123- f' { account_name } /{ repo_name } ' )
128+ raise GitHubError ('Failed to get GitHub repository data for'
129+ f' { account_name } /{ repo_name } .'
130+ ' This could be due to a number of causes. Please'
131+ ' check that the repository and release do exist, and'
132+ ' that the GitHub access token (if one is being used)'
133+ ' is configured with appropriate permissions to grant'
134+ ' access to the repository.' )
124135 return result
125136
126137
@@ -130,7 +141,12 @@ def github_account(account_name):
130141 log ('getting GitHub data for user at ' + endpoint )
131142 result = _object_for_github (endpoint , GitHubAccount )
132143 if not result :
133- raise GitHubError (f'Can\' t get GitHub account data for { account_name } ' )
144+ raise GitHubError (f'Failed to get GitHub account data for { account_name } .'
145+ ' This could be due to a number of causes. Please'
146+ ' check that the account exists, and that the GitHub'
147+ ' access token (if one is being used) is configured'
148+ ' with appropriate permissions to grant access to'
149+ ' user account data.' )
134150 return result
135151
136152
@@ -355,26 +371,39 @@ def _github_get(endpoint):
355371 using_token = 'GITHUB_TOKEN' in os .environ
356372 if using_token :
357373 headers ['Authorization' ] = f'token { os .environ ["GITHUB_TOKEN" ]} '
358- try :
359- response = network ('get' , endpoint , headers = headers )
360- return response # noqa PIE787
361- except KeyboardInterrupt :
362- raise
363- except commonpy .exceptions .NoContent :
374+ (response , error ) = net ('get' , endpoint , headers = headers )
375+ if not error :
376+ return response
377+ elif isinstance (error , commonpy .exceptions .NoContent ):
364378 log (f'got no content for { endpoint } ' )
365- except commonpy .exceptions .AuthenticationFailure :
379+ elif isinstance ( error , commonpy .exceptions .AuthenticationFailure ) :
366380 # GitHub is unusual in returning 403 when you hit the rate limit.
367381 # https://docs.github.com/en/rest/overview/resources-in-the-rest-api
368- if 'API rate limit exceeded' in response .text :
382+ # This means an authentication failure could be due to rate limits OR
383+ # a credentials problems, and we have to try to figure out which one.
384+ message = ''
385+ with contextlib .suppress (Exception ):
386+ if response and not isinstance (response , str ):
387+ # Preferable case: if the response value from net() is not a
388+ # str, it'll be an httpx object & should have a message
389+ # field. This will have more specific details than the
390+ # generic Exception object we stored in the error variable.
391+ message = response .json ().get ('message' )
392+ else :
393+ # Didn't get a response object. Use the text from the Exception.
394+ message = getattr (error , 'text' , '' )
395+ # Now try to distinguish what caused this GitHub error.
396+ if 'rate limit' in message :
369397 if using_token :
370- raise GitHubError ('Rate limit exceeded – try again later' )
398+ raise GitHubError ('GitHub rate limit exceeded – try again later' )
371399 else :
372- raise GitHubError ('Rate limit exceeded – try to use a personal'
400+ raise GitHubError ('GitHub rate limit exceeded – try to use a personal'
373401 ' access token, or wait and try again later.' )
374402 else :
375- raise GitHubError ('Permissions problem accessing ' + endpoint )
376- except commonpy .exceptions .CommonPyException as ex :
377- raise GitHubError (ex .args [0 ]) from ex
378- except Exception :
379- raise
403+ details = f' ("{ message } ")' if message else ''
404+ raise GitHubError (f'GitHub permissions error{ details } accessing { endpoint } ' )
405+ elif isinstance (error , commonpy .exceptions .CommonPyException ):
406+ raise GitHubError (error .args [0 ]) from error
407+ else :
408+ raise error
380409 return None
0 commit comments