diff --git a/src/github/AuthenticatedUser.py b/src/github/AuthenticatedUser.py index 55cdd7f9..c5f6eb0a 100644 --- a/src/github/AuthenticatedUser.py +++ b/src/github/AuthenticatedUser.py @@ -148,7 +148,7 @@ class AuthenticatedUser( object ): return self.__url def add_to_emails( self, *emails ): - assert len( emails ) == 0 or isinstance( emails[ 0 ], ( str, unicode ) ), emails + assert all( isinstance( email, ( str, unicode ) ) for email in emails ), emails post_parameters = emails status, headers, data = self.__requester.request( "POST", @@ -238,6 +238,8 @@ class AuthenticatedUser( object ): None, post_parameters ) + if self.__requester.isFailureStatus( status ): + raise GithubException( status, data ) return UserKey.UserKey( self.__requester, data, completion = NoCompletion ) def create_repo( self, name, description = DefaultValueForOptionalParameters, homepage = DefaultValueForOptionalParameters, private = DefaultValueForOptionalParameters, has_issues = DefaultValueForOptionalParameters, has_wiki = DefaultValueForOptionalParameters, has_downloads = DefaultValueForOptionalParameters ): diff --git a/src/github/GithubObject.py b/src/github/GithubObject.py index e36123a7..55ae0e62 100644 --- a/src/github/GithubObject.py +++ b/src/github/GithubObject.py @@ -6,3 +6,9 @@ DefaultValueForOptionalParameters = DefaultValueForOptionalParametersType() LazyCompletion = 0 ImmediateCompletion = 1 NoCompletion = 2 + +class GithubException( Exception ): + def __init__( self, status, data ): + Exception.__init__( self ) + self.status = status + self.data = data diff --git a/src/github/Requester.py b/src/github/Requester.py index 8ccb30b8..06f3f430 100644 --- a/src/github/Requester.py +++ b/src/github/Requester.py @@ -3,9 +3,6 @@ import json import base64 import urllib -class UnknownGithubObject( Exception ): - pass - class Requester: def __init__( self, login_or_token, password ): if password is not None: @@ -61,3 +58,6 @@ class Requester: def parentUrl( self, url ): return "/".join( url.split( "/" )[ : -1 ] ) + + def isFailureStatus( self, status ): + return status >= 400 diff --git a/src/github/__init__.py b/src/github/__init__.py index 109d6b9a..392e4617 100644 --- a/src/github/__init__.py +++ b/src/github/__init__.py @@ -1 +1,2 @@ from Github import Github +from GithubObject import GithubException diff --git a/test/Exceptions.py b/test/Exceptions.py new file mode 100644 index 00000000..0f83c9d8 --- /dev/null +++ b/test/Exceptions.py @@ -0,0 +1,23 @@ +import github + +import Framework + +class Exceptions( Framework.TestCase ): + def testInvalidInput( self ): + with self.assertRaises( github.GithubException ) as cm: + self.g.get_user().create_key( "Bad key", "xxx" ) + self.assertEqual( cm.exception.status, 422 ) + self.assertEqual( + cm.exception.data, + { + "errors": [ + { + "code": "custom", + "field": "key", + "message": "key is invalid. It must begin with 'ssh-rsa' or 'ssh-dss'. Check that you're copying the public half of the key", + "resource": "PublicKey" + } + ], + "message": "Validation Failed" + } + ) diff --git a/test/IntegrationTest.py b/test/IntegrationTest.py index f2a0b279..4a3eaf89 100644 --- a/test/IntegrationTest.py +++ b/test/IntegrationTest.py @@ -38,5 +38,6 @@ from UserKey import * from PaginatedList import * from Issue33 import * +from Exceptions import * Framework.main() diff --git a/test/ReplayData/Exceptions.testInvalidInput.txt b/test/ReplayData/Exceptions.testInvalidInput.txt new file mode 100644 index 00000000..44ce6375 --- /dev/null +++ b/test/ReplayData/Exceptions.testInvalidInput.txt @@ -0,0 +1,5 @@ +POST /user/keys {'Authorization': 'Basic login_and_password_removed'} {"key": "xxx", "title": "Bad key"} +422 +[('status', '422 Unprocessable Entity'), ('x-ratelimit-remaining', '4995'), ('content-length', '221'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"73f756ef75655dd74463eb1bf4cfefe1"'), ('date', 'Wed, 30 May 2012 07:00:27 GMT'), ('content-type', 'application/json; charset=utf-8')] +{"message":"Validation Failed","errors":[{"field":"key","resource":"PublicKey","message":"key is invalid. It must begin with 'ssh-rsa' or 'ssh-dss'. Check that you're copying the public half of the key","code":"custom"}]} +