diff options
author | Giuseppe Lavagetto <lavagetto@gmail.com> | 2015-02-22 11:52:59 +0100 |
---|---|---|
committer | Giuseppe Lavagetto <lavagetto@gmail.com> | 2015-02-22 11:52:59 +0100 |
commit | ce3e8f0fa3f4802afebba7990260e07f5b8f0e4e (patch) | |
tree | d87bf31cd95626d773ca6726bc1dfd00f52a8908 /src | |
parent | 2cfb11a75f6605b87da3f01b79a8ee2d0d632662 (diff) | |
parent | 31d5257a491cf9f7f19a9420a75e4b141007b8ca (diff) |
Merge branch 'shakim-enhance-exception-information'
Diffstat (limited to 'src')
-rw-r--r-- | src/etcd/__init__.py | 58 | ||||
-rw-r--r-- | src/etcd/client.py | 2 | ||||
-rw-r--r-- | src/etcd/tests/integration/test_election.py | 2 | ||||
-rw-r--r-- | src/etcd/tests/integration/test_simple.py | 11 | ||||
-rw-r--r-- | src/etcd/tests/unit/test_old_request.py | 10 | ||||
-rw-r--r-- | src/etcd/tests/unit/test_request.py | 2 |
6 files changed, 65 insertions, 20 deletions
diff --git a/src/etcd/__init__.py b/src/etcd/__init__.py index 600a60c..9da1049 100644 --- a/src/etcd/__init__.py +++ b/src/etcd/__init__.py @@ -105,19 +105,56 @@ class EtcdException(Exception): """ Generic Etcd Exception. """ + def __init__(self, message=None, payload=None): + super(Exception, self).__init__(message) + self.payload=payload + +class EtcdKeyError(EtcdException): + """ + Etcd Generic KeyError Exception + """ + pass + +class EtcdKeyNotFound(EtcdKeyError): + """ + Etcd key not found exception (100) + """ + pass + +class EtcdNotFile(EtcdKeyError): + """ + Etcd not a file exception (102) + """ pass +class EtcdNotDir(EtcdKeyError): + """ + Etcd not a directory exception (104) + """ + pass + +class EtcdAlreadyExist(EtcdKeyError): + """ + Etcd already exist exception (105) + """ + pass + +class EtcdEventIndexCleared(EtcdException): + """ + Etcd event index is outdated and cleared exception (401) + """ + pass class EtcdError(object): # See https://github.com/coreos/etcd/blob/master/Documentation/errorcode.md error_exceptions = { - 100: KeyError, + 100: EtcdKeyNotFound, 101: ValueError, - 102: KeyError, + 102: EtcdNotFile, 103: Exception, - 104: KeyError, - 105: KeyError, + 104: EtcdNotDir, + 105: EtcdAlreadyExist, 106: KeyError, 200: ValueError, 201: ValueError, @@ -126,7 +163,7 @@ class EtcdError(object): 300: Exception, 301: Exception, 400: Exception, - 401: EtcdException, + 401: EtcdEventIndexCleared, 500: EtcdException } @@ -134,12 +171,19 @@ class EtcdError(object): def handle(cls, errorCode=None, message=None, cause=None, **kwdargs): """ Decodes the error and throws the appropriate error message""" try: - msg = "{} : {}".format(message, cause) + msg = '{} : {}'.format(message, cause) + payload={'errorCode': errorCode, 'message': message, 'cause': cause} + if len(kwdargs) > 0: + for key in kwdargs: + payload[key]=kwdargs[key] exc = cls.error_exceptions[errorCode] except: msg = "Unable to decode server response" exc = EtcdException - raise exc(msg) + if exc in [EtcdException, EtcdKeyNotFound, EtcdNotFile, EtcdNotDir, EtcdAlreadyExist, EtcdEventIndexCleared]: + raise exc(msg, payload) + else: + raise exc(msg) # Attempt to enable urllib3's SNI support, if possible diff --git a/src/etcd/client.py b/src/etcd/client.py index 271d85e..516e335 100644 --- a/src/etcd/client.py +++ b/src/etcd/client.py @@ -202,7 +202,7 @@ class Client(object): try: self.get(key) return True - except KeyError: + except etcd.EtcdKeyNotFound: return False def _sanitize_key(self, key): diff --git a/src/etcd/tests/integration/test_election.py b/src/etcd/tests/integration/test_election.py index 76f397b..46ea2bb 100644 --- a/src/etcd/tests/integration/test_election.py +++ b/src/etcd/tests/integration/test_election.py @@ -31,4 +31,4 @@ class TestElection(test_simple.EtcdIntegrationTest): e.set('/mysql', name='foo', ttl=1) time.sleep(2) self.assertRaises(etcd.EtcdException, e.get, '/mysql') - self.assertRaises(KeyError, e.delete, '/mysql', name='foo') + self.assertRaises(etcd.EtcdKeyNotFound, e.delete, '/mysql', name='foo') diff --git a/src/etcd/tests/integration/test_simple.py b/src/etcd/tests/integration/test_simple.py index 50530e9..9283cc5 100644 --- a/src/etcd/tests/integration/test_simple.py +++ b/src/etcd/tests/integration/test_simple.py @@ -74,7 +74,7 @@ class TestSimple(EtcdIntegrationTest): try: get_result = self.client.get('/test_set') assert False - except KeyError as e: + except etcd.EtcdKeyNotFound as e: pass self.assertFalse('/test_set' in self.client) @@ -100,7 +100,7 @@ class TestSimple(EtcdIntegrationTest): try: get_result = self.client.get('/test_set') assert False - except KeyError as e: + except etcd.EtcdKeyNotFound as e: pass def test_update(self): @@ -120,7 +120,7 @@ class TestSimple(EtcdIntegrationTest): set_result = self.client.write('/subtree/test_set2', 'test-key3') get_result = self.client.read('/subtree', recursive=True) result = [subkey.value for subkey in get_result.leaves] - self.assertEquals(['test-key1', 'test-key2', 'test-key3'], result) + self.assertEquals(['test-key1', 'test-key2', 'test-key3'].sort(), result.sort()) def test_directory_ttl_update(self): """ INTEGRATION: should be able to update a dir TTL """ @@ -140,7 +140,7 @@ class TestErrors(EtcdIntegrationTest): """ INTEGRATION: try to write value to an existing directory """ self.client.set('/directory/test-key', 'test-value') - self.assertRaises(KeyError, self.client.set, '/directory', 'test-value') + self.assertRaises(etcd.EtcdNotFile, self.client.set, '/directory', 'test-value') def test_test_and_set(self): """ INTEGRATION: try test_and_set operation """ @@ -159,7 +159,8 @@ class TestErrors(EtcdIntegrationTest): `prevExist=True` should fail """ self.client.write('/mydir', None, dir=True) - self.assertRaises(KeyError, self.client.write, '/mydir', None, dir=True) + self.assertRaises(etcd.EtcdNotFile, self.client.write, '/mydir', None, dir=True) + self.assertRaises(etcd.EtcdAlreadyExist, self.client.write, '/mydir', None, dir=True, prevExist=False) class TestClusterFunctions(EtcdIntegrationTest): diff --git a/src/etcd/tests/unit/test_old_request.py b/src/etcd/tests/unit/test_old_request.py index e449b7d..9367ebd 100644 --- a/src/etcd/tests/unit/test_old_request.py +++ b/src/etcd/tests/unit/test_old_request.py @@ -171,7 +171,7 @@ class TestClientRequest(unittest.TestCase): def test_not_in(self): """ Can check if key is not in client """ client = etcd.Client() - client.get = mock.Mock(side_effect=KeyError()) + client.get = mock.Mock(side_effect=etcd.EtcdKeyNotFound()) result = '/testkey' not in client self.assertEquals(True, result) @@ -307,8 +307,8 @@ class TestClientApiExecutor(unittest.TestCase): try: client.api_execute('/v2/keys/testkey', client._MGET) assert False - except KeyError as e: - self.assertEquals(str(e), "'message : cause'") + except etcd.EtcdKeyNotFound as e: + self.assertEquals(str(e), 'message : cause') def test_put(self): """ http put request """ @@ -357,8 +357,8 @@ class TestClientApiExecutor(unittest.TestCase): try: client.api_execute('/v2/keys/testkey', client._MPUT, payload) self.fail() - except KeyError as e: - self.assertEquals("'message : cause'", str(e)) + except etcd.EtcdNotFile as e: + self.assertEquals('message : cause', str(e)) def test_get_error_unknown(self): """ http get error request unknown """ diff --git a/src/etcd/tests/unit/test_request.py b/src/etcd/tests/unit/test_request.py index 7103fa1..df1ae57 100644 --- a/src/etcd/tests/unit/test_request.py +++ b/src/etcd/tests/unit/test_request.py @@ -282,7 +282,7 @@ class TestClientApiInterface(TestClientApiBase): def test_not_in(self): """ Can check if key is not in client """ - self._mock_exception(KeyError, 'Key not Found : /testKey') + self._mock_exception(etcd.EtcdKeyNotFound, 'Key not Found : /testKey') self.assertTrue('/testey' not in self.client) def test_in(self): |