Skip to content

Commit

Permalink
Re-raise the exception when failing to parse JSON
Browse files Browse the repository at this point in the history
Since GitHub has the bad manners to return bare strings for some API
endpoints, one sharp edge has been that JSON decoding errors were masked
since we wrap the string in a dictionary. However, this makes it
difficult to debug malformed JSON in replay data, so re-raise the
exception if the first character is a { or [ (IE, it's an object or
list.)
  • Loading branch information
s-t-e-v-e-n-k committed Mar 24, 2021
1 parent 0245b75 commit 1432e41
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 2 deletions.
2 changes: 2 additions & 0 deletions github/Requester.py
Expand Up @@ -441,6 +441,8 @@ def __structuredFromJson(self, data):
try:
return json.loads(data)
except ValueError:
if data.startswith("{") or data.startswith("["):
raise
return {"data": data}

def requestJson(
Expand Down
5 changes: 5 additions & 0 deletions tests/Exceptions.py
Expand Up @@ -92,6 +92,11 @@ def testBadAuthentication(self):
def testExceptionPickling(self):
pickle.loads(pickle.dumps(github.GithubException("foo", "bar", None)))

def testJSONParseError(self):
# Replay data was forged to force a JSON error
with self.assertRaises(ValueError):
self.g.get_user("jacquev6")


class SpecificExceptions(Framework.TestCase):
def testBadCredentials(self):
Expand Down
10 changes: 10 additions & 0 deletions tests/ReplayData/Exceptions.testJSONParseError.txt
@@ -0,0 +1,10 @@
https
GET
api.github.com
None
/users/jacquev6
{'User-Agent': 'PyGithub/Python', 'Authorization': 'Basic login_and_password_removed'}
None
200
[('status', '200 OK'), ('x-ratelimit-remaining', '2'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('access-control-allow-credentials', 'true'), ('vary', 'Accept, Accept-Encoding'), ('content-length', '1299'), ('server', 'GitHub.com'), ('last-modified', 'Fri, 17 May 2013 12:09:51 GMT'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '60'), ('etag', '"de9347ae9c0c83b44d6c81d05aba4877"'), ('cache-control', 'public, max-age=60, s-maxage=60'), ('date', 'Fri, 17 May 2013 12:23:52 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8')]
{"login":"jacquev6","id":327146,"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2F
2 changes: 1 addition & 1 deletion tests/ReplayData/Organization.testAddMembersAdminRole.txt
Expand Up @@ -29,7 +29,7 @@ None
{"role": "admin"}
200
[('content-length', '1718'), ('x-runtime-rack', '0.264296'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('x-oauth-scopes', 'admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', 'admin:org, repo'), ('etag', '"00000000000000000000000000000000"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4995'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('x-github-request-id', '0000:0000:000000:0000000:00000000'), ('date', 'Fri, 06 Apr 2018 12:54:57 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1523022613')]
{"url":"https://api.github.com/orgs/BeaverSoftware/memberships/lyloa","state":"pending", "role":"member","organization_url":"https://api.github.com/orgs/BeaverSoftware","user":{"login":"lyloa","id":1,"avatar_url":"https://avatars1.githubusercontent.com/u/28614060?v=4","gravatar_id":"","url":"https://api.github.com/users/lyloa","html_url":"https://github.com/lyloa","followers_url":"https://api.github.com/users/lyloa/followers","following_url":"https://api.github.com/users/lyloa/following{/other_user}","gists_url":"https://api.github.com/users/lyloa/gists{/gist_id}","starred_url":"https://api.github.com/users/lyloa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lyloa/subscriptions","organizations_url":"https://api.github.com/users/lyloa/orgs","repos_url":"https://api.github.com/users/lyloa/repos","events_url":"https://api.github.com/users/lyloa/events{/privacy}","received_events_url":"https://api.github.com/users/lyloa/received_events","type":"User","site_admin":false},"organization":{"login":"BeaverSoftware","id":0000000,"url":"https://api.github.com/orgs/BeaverSoftware","repos_url":"https://api.github.com/orgs/BeaverSoftware/repos","events_url":"https://api.github.com/orgs/BeaverSoftware/events","hooks_url":"https://api.github.com/orgs/BeaverSoftware/hooks","issues_url":"https://api.github.com/orgs/BeaverSoftware/issues","members_url":"https://api.github.com/orgs/BeaverSoftware/members{/member}","public_members_url":"https://api.github.com/orgs/BeaverSoftware/public_members{/member}","avatar_url":"https://avatars1.githubusercontent.com/u/6361338?v=4","description":"Beaver Software is dead.."}}
{"url":"https://api.github.com/orgs/BeaverSoftware/memberships/lyloa","state":"pending", "role":"member","organization_url":"https://api.github.com/orgs/BeaverSoftware","user":{"login":"lyloa","id":1,"avatar_url":"https://avatars1.githubusercontent.com/u/28614060?v=4","gravatar_id":"","url":"https://api.github.com/users/lyloa","html_url":"https://github.com/lyloa","followers_url":"https://api.github.com/users/lyloa/followers","following_url":"https://api.github.com/users/lyloa/following{/other_user}","gists_url":"https://api.github.com/users/lyloa/gists{/gist_id}","starred_url":"https://api.github.com/users/lyloa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lyloa/subscriptions","organizations_url":"https://api.github.com/users/lyloa/orgs","repos_url":"https://api.github.com/users/lyloa/repos","events_url":"https://api.github.com/users/lyloa/events{/privacy}","received_events_url":"https://api.github.com/users/lyloa/received_events","type":"User","site_admin":false},"organization":{"login":"BeaverSoftware","id":0,"url":"https://api.github.com/orgs/BeaverSoftware","repos_url":"https://api.github.com/orgs/BeaverSoftware/repos","events_url":"https://api.github.com/orgs/BeaverSoftware/events","hooks_url":"https://api.github.com/orgs/BeaverSoftware/hooks","issues_url":"https://api.github.com/orgs/BeaverSoftware/issues","members_url":"https://api.github.com/orgs/BeaverSoftware/members{/member}","public_members_url":"https://api.github.com/orgs/BeaverSoftware/public_members{/member}","avatar_url":"https://avatars1.githubusercontent.com/u/6361338?v=4","description":"Beaver Software is dead.."}}

https
GET
Expand Down
Expand Up @@ -29,7 +29,7 @@ None
{"role": "member"}
200
[('content-length', '1718'), ('x-runtime-rack', '0.352123'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('x-oauth-scopes', 'admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', 'admin:org, repo'), ('etag', '"92186"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4972'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('x-github-request-id', 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'), ('date', 'Thu, 05 Apr 2018 17:09:06 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1522950939')]
{"url":"https://api.github.com/orgs/BeaverSoftware/memberships/lyloa","state":"pending", "role":"member","organization_url":"https://api.github.com/orgs/BeaverSoftware","user":{"login":"lyloa","id":1,"avatar_url":"https://avatars1.githubusercontent.com/u/28614060?v=4","gravatar_id":"","url":"https://api.github.com/users/lyloa","html_url":"https://github.com/lyloa","followers_url":"https://api.github.com/users/lyloa/followers","following_url":"https://api.github.com/users/lyloa/following{/other_user}","gists_url":"https://api.github.com/users/lyloa/gists{/gist_id}","starred_url":"https://api.github.com/users/lyloa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lyloa/subscriptions","organizations_url":"https://api.github.com/users/lyloa/orgs","repos_url":"https://api.github.com/users/lyloa/repos","events_url":"https://api.github.com/users/lyloa/events{/privacy}","received_events_url":"https://api.github.com/users/lyloa/received_events","type":"User","site_admin":false},"organization":{"login":"BeaverSoftware","id":0000000,"url":"https://api.github.com/orgs/BeaverSoftware","repos_url":"https://api.github.com/orgs/BeaverSoftware/repos","events_url":"https://api.github.com/orgs/BeaverSoftware/events","hooks_url":"https://api.github.com/orgs/BeaverSoftware/hooks","issues_url":"https://api.github.com/orgs/BeaverSoftware/issues","members_url":"https://api.github.com/orgs/BeaverSoftware/members{/member}","public_members_url":"https://api.github.com/orgs/BeaverSoftware/public_members{/member}","avatar_url":"https://avatars1.githubusercontent.com/u/6361338?v=4","description":"Beaver Software is dead.."}}
{"url":"https://api.github.com/orgs/BeaverSoftware/memberships/lyloa","state":"pending", "role":"member","organization_url":"https://api.github.com/orgs/BeaverSoftware","user":{"login":"lyloa","id":1,"avatar_url":"https://avatars1.githubusercontent.com/u/28614060?v=4","gravatar_id":"","url":"https://api.github.com/users/lyloa","html_url":"https://github.com/lyloa","followers_url":"https://api.github.com/users/lyloa/followers","following_url":"https://api.github.com/users/lyloa/following{/other_user}","gists_url":"https://api.github.com/users/lyloa/gists{/gist_id}","starred_url":"https://api.github.com/users/lyloa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lyloa/subscriptions","organizations_url":"https://api.github.com/users/lyloa/orgs","repos_url":"https://api.github.com/users/lyloa/repos","events_url":"https://api.github.com/users/lyloa/events{/privacy}","received_events_url":"https://api.github.com/users/lyloa/received_events","type":"User","site_admin":false},"organization":{"login":"BeaverSoftware","id":0,"url":"https://api.github.com/orgs/BeaverSoftware","repos_url":"https://api.github.com/orgs/BeaverSoftware/repos","events_url":"https://api.github.com/orgs/BeaverSoftware/events","hooks_url":"https://api.github.com/orgs/BeaverSoftware/hooks","issues_url":"https://api.github.com/orgs/BeaverSoftware/issues","members_url":"https://api.github.com/orgs/BeaverSoftware/members{/member}","public_members_url":"https://api.github.com/orgs/BeaverSoftware/public_members{/member}","avatar_url":"https://avatars1.githubusercontent.com/u/6361338?v=4","description":"Beaver Software is dead.."}}

https
GET
Expand Down

0 comments on commit 1432e41

Please sign in to comment.