From 0678b1df25a7f11a33ad46b99fdd357f8ae61ffc Mon Sep 17 00:00:00 2001 From: Ryan Barrett <git@ryanb.org> Date: Sun, 27 May 2018 20:55:35 -0700 Subject: [PATCH] github: better error handling for creating comments, surface messages fixes snarfed/bridgy#824 --- granary/github.py | 23 +++++++++++++++-------- granary/test/test_github.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/granary/github.py b/granary/github.py index 2e06bff3..a6d2a7a6 100644 --- a/granary/github.py +++ b/granary/github.py @@ -235,7 +235,12 @@ def graphql(self, graphql, kwargs): }) resp.raise_for_status() result = resp.json() - assert 'errors' not in result, result + + errs = result.get('errors') + if errs: + logging.warning(result) + raise ValueError('\n'.join(e.get('message') for e in errs)) + return result['data'] def rest(self, url, data=None, **kwargs): @@ -418,7 +423,7 @@ def render_markdown(self, markdown, owner, repo): Returns: unicode string, rendered HTML """ - return self.rest (REST_API_MARKDOWN, { + return self.rest(REST_API_MARKDOWN, { 'text': markdown, 'mode': 'gfm', 'context': '%s/%s' % (owner, repo), @@ -480,7 +485,6 @@ def _create(self, obj, preview=None, include_link=source.OMIT_LINK, If preview is True, the contents will be a unicode string HTML snippet. If False, it will be a dict with 'id' and 'url' keys for the newly created GitHub object. - """ assert preview in (False, True) @@ -609,11 +613,14 @@ def _create(self, obj, preview=None, include_link=source.OMIT_LINK, }) else: - resp = self.graphql(GRAPHQL_ADD_COMMENT, { - 'subject_id': issue['id'], - 'body': content, - }) - return source.creation_result(resp['addComment']['commentEdge']['node']) + try: + resp = self.graphql(GRAPHQL_ADD_COMMENT, { + 'subject_id': issue['id'], + 'body': content, + }) + return source.creation_result(resp['addComment']['commentEdge']['node']) + except ValueError as e: + return source.creation_result(abort=True, error_plain=unicode(e)) return source.creation_result( abort=False, diff --git a/granary/test/test_github.py b/granary/test/test_github.py index ec2f480d..2855b635 100644 --- a/granary/test/test_github.py +++ b/granary/test/test_github.py @@ -795,6 +795,40 @@ def test_preview_issue_tags_to_labels(self): preview.description, preview) def test_create_comment_without_in_reply_to(self): + msg = 'Although you appear to have the correct authorization credentials,\nthe `whatwg` organization has enabled OAuth App access restrictions, meaning that data\naccess to third-parties is limited. For more information on these restrictions, including\nhow to whitelist this app, visit\nhttps://help.github.com/articles/restricting-access-to-your-organization-s-data/\n' + + self.expect_graphql_issue() + self.expect_requests_post( + GRAPHQL_BASE, + headers={'Authorization': 'bearer a-towkin'}, + json={ + 'query': github.GRAPHQL_ADD_COMMENT % { + 'subject_id': ISSUE_GRAPHQL['id'], + 'body': COMMENT_OBJ['content'], + }, + }, + # status_code=403, + response={ + 'errors': [ + { + 'path': ['addComment'], + 'message': msg, + 'type': 'FORBIDDEN', + 'locations': [{'column': 3, 'line': 3}], + }, + ], + 'data': { + 'addComment': None, + }, + }) + self.mox.ReplayAll() + + result = self.gh.create(COMMENT_OBJ) + self.assertTrue(result.abort) + self.assertEquals(msg, result.error_plain) + + def test_create_comment_org_access_forbidden(self): + """https://github.com/snarfed/bridgy/issues/824""" obj = copy.deepcopy(COMMENT_OBJ) obj['inReplyTo'] = [{'url': 'http://foo.com/bar'}]