Make Requester.__createException robust against missing message and body (#2159)

This commit is contained in:
Enrico Minack
2023-06-13 11:14:14 +02:00
committed by GitHub
parent 6407512079
commit 7be3f76372
2 changed files with 131 additions and 9 deletions
+8 -8
View File
@@ -422,7 +422,9 @@ class Requester:
return cnx
def __createException(self, status, headers, output):
if status == 401 and output.get("message") == "Bad credentials":
message = output.get("message", "").lower() if output is not None else ""
if status == 401 and message == "bad credentials":
cls = GithubException.BadCredentialsException
elif (
status == 401
@@ -430,18 +432,16 @@ class Requester:
and re.match(r".*required.*", headers[Consts.headerOTP])
):
cls = GithubException.TwoFactorException
elif status == 403 and output.get("message").startswith(
"Missing or invalid User Agent string"
elif status == 403 and message.startswith(
"missing or invalid user agent string"
):
cls = GithubException.BadUserAgentException
elif status == 403 and (
output.get("message").lower().startswith("api rate limit exceeded")
or output.get("message")
.lower()
.endswith("please wait a few minutes before you try again.")
message.startswith("api rate limit exceeded")
or message.endswith("please wait a few minutes before you try again.")
):
cls = GithubException.RateLimitExceededException
elif status == 404 and output.get("message") == "Not Found":
elif status == 404 and message == "not found":
cls = GithubException.UnknownObjectException
else:
cls = GithubException.GithubException
+123 -1
View File
@@ -1,6 +1,6 @@
############################ Copyrights and license ############################
# #
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
# Copyright 2022 Enrico Minack <github@enrico.minack.dev> #
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
@@ -91,3 +91,125 @@ class Requester(Framework.TestCase):
self.logger.info.assert_called_once_with(
"Following Github server redirection from /api/v3/repos/PyGithub/PyGithub to /repos/PyGithub/PyGithub"
)
def assertException(self, exception, exception_type, status, data, headers, string):
self.assertIsInstance(exception, exception_type)
self.assertEqual(exception.status, status)
if data is None:
self.assertIsNone(exception.data)
else:
self.assertEqual(exception.data, data)
self.assertEqual(exception.headers, headers)
self.assertEqual(str(exception), string)
def testShouldCreateBadCredentialsException(self):
exc = self.g._Github__requester.__createException(
401, {"header": "value"}, {"message": "Bad credentials"}
)
self.assertException(
exc,
github.BadCredentialsException,
401,
{"message": "Bad credentials"},
{"header": "value"},
'401 {"message": "Bad credentials"}',
)
def testShouldCreateTwoFactorException(self):
exc = self.g._Github__requester.__createException(
401,
{"x-github-otp": "required; app"},
{
"message": "Must specify two-factor authentication OTP code.",
"documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication",
},
)
self.assertException(
exc,
github.TwoFactorException,
401,
{
"message": "Must specify two-factor authentication OTP code.",
"documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication",
},
{"x-github-otp": "required; app"},
'401 {"message": "Must specify two-factor authentication OTP code.", "documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication"}',
)
def testShouldCreateBadUserAgentException(self):
exc = self.g._Github__requester.__createException(
403,
{"header": "value"},
{"message": "Missing or invalid User Agent string"},
)
self.assertException(
exc,
github.BadUserAgentException,
403,
{"message": "Missing or invalid User Agent string"},
{"header": "value"},
'403 {"message": "Missing or invalid User Agent string"}',
)
def testShouldCreateRateLimitExceededException(self):
for message in [
"API Rate Limit Exceeded for 92.104.200.119",
"You have triggered an abuse detection mechanism. Please wait a few minutes before you try again.",
"You have exceeded a secondary rate limit. Please wait a few minutes before you try again.",
]:
with self.subTest(message=message):
exc = self.g._Github__requester.__createException(
403, {"header": "value"}, {"message": message}
)
self.assertException(
exc,
github.RateLimitExceededException,
403,
{"message": message},
{"header": "value"},
f'403 {{"message": "{message}"}}',
)
def testShouldCreateUnknownObjectException(self):
exc = self.g._Github__requester.__createException(
404, {"header": "value"}, {"message": "Not Found"}
)
self.assertException(
exc,
github.UnknownObjectException,
404,
{"message": "Not Found"},
{"header": "value"},
'404 {"message": "Not Found"}',
)
def testShouldCreateGithubException(self):
for status in range(400, 600):
with self.subTest(status=status):
exc = self.g._Github__requester.__createException(
status, {"header": "value"}, {"message": "Something unknown"}
)
self.assertException(
exc,
github.GithubException,
status,
{"message": "Something unknown"},
{"header": "value"},
f'{status} {{"message": "Something unknown"}}',
)
def testShouldCreateExceptionWithoutMessage(self):
for status in range(400, 600):
with self.subTest(status=status):
exc = self.g._Github__requester.__createException(status, {}, {})
self.assertException(
exc, github.GithubException, status, {}, {}, f"{status} {{}}"
)
def testShouldCreateExceptionWithoutOutput(self):
for status in range(400, 600):
with self.subTest(status=status):
exc = self.g._Github__requester.__createException(status, {}, None)
self.assertException(
exc, github.GithubException, status, None, {}, f"{status} null"
)