Skip to content

Commit

Permalink
error_chain can now be read when an error happens
Browse files Browse the repository at this point in the history
  • Loading branch information
mahtin committed Oct 21, 2016
1 parent 5f78fcd commit 3650b3e
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 10 deletions.
15 changes: 12 additions & 3 deletions CloudFlare/cloudflare.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,18 @@ def _call(self, method, headers,
if response_data['success'] is False:
code = response_data['errors'][0]['code']
message = response_data['errors'][0]['message']
if self.logger:
self.logger.debug('Response: error %d %s' % (code, message))
raise CloudFlareAPIError(code, message)
if 'error_chain' in response_data['errors'][0]:
error_chain = response_data['errors'][0]['error_chain']
for error in error_chain:
if self.logger:
self.logger.debug('Response: error %d %s - chain' % (error['code'], error['message']))
if self.logger:
self.logger.debug('Response: error %d %s' % (code, message))
raise CloudFlareAPIError(code, message, error_chain)
else:
if self.logger:
self.logger.debug('Response: error %d %s' % (code, message))
raise CloudFlareAPIError(code, message)

if self.logger:
self.logger.debug('Response: %s' % (response_data['result']))
Expand Down
55 changes: 48 additions & 7 deletions CloudFlare/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,62 @@
class CloudFlareError(Exception):
""" errors for Cloudflare API"""

def __init__(self, code, message):
class _code_message(object):
""" a small class to save away an interger and string (the code and the message)"""

def __init__(self, code, message):
self.code = code
self.message = message
def __int__(self):
return self.code
def __str__(self):
return self.message

def __init__(self, code, message, error_chain=None):
""" errors for Cloudflare API"""

self.code = code
self.message = message
self.e = self._code_message(int(code), str(message))
self.error_chain = None
if error_chain != None:
self.error_chain = []
for e in error_chain:
self.error_chain.append(self._code_message(int(e['code']), str(e['message'])))
# self.error_chain.append({'code': self.code, 'message': str(self.message)})

def __int__(self):
""" errors for Cloudflare API"""
""" integer value for Cloudflare API errors"""

return self.code
return int(self.e)

def __str__(self):
""" errors for Cloudflare API"""
""" string value for Cloudflare API errors"""

return str(self.e)

def __len__(self):
""" Cloudflare API errors can contain a chain of errors"""

if self.error_chain == None:
return 0
else:
return len(self.error_chain)

def __getitem__(self, ii):
""" Cloudflare API errors can contain a chain of errors"""

return self.error_chain[ii]

def __iter__(self):
""" Cloudflare API errors can contain a chain of errors"""

if self.error_chain == None:
raise StopIteration
for e in self.error_chain:
yield e

return self.message
def next(self):
if self.error_chain == None:
raise StopIteration()

class CloudFlareAPIError(CloudFlareError):
""" errors for Cloudflare API"""
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,26 @@ import CloudFlare.exceptions

The other raised response is **CloudFlareInternalError** which can happen when calling an invalid method.

In some cases more than one error is returned. In this case the return value **e** is also an array.
You can itterate over that array to see the additional error.

```python
import sys
import CloudFlare
import CloudFlare.exceptions

...
try
r = ...
except CloudFlare.exceptions.CloudFlareAPIError as e:
if len(e) > 0:
sys.stderr.write('api error - more than one error value returned!\n')
for x in e:
sys.stderr.write('api error: %d %s\n' % (x, x))
exit('api error: %d %s' % (e, e))
...
```

## Included example code

The [examples](https://github.com/cloudflare/python-cloudflare/tree/master/examples) folder contains many examples in both simple and verbose formats.
Expand Down
21 changes: 21 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,27 @@ The exception returns both an integer and textual message in one value.
The other raised response is **CloudFlareInternalError** which can
happen when calling an invalid method.

In some cases more than one error is returned. In this case the return
value **e** is also an array. You can itterate over that array to see
the additional error.

.. code:: python
import sys
import CloudFlare
import CloudFlare.exceptions
...
try
r = ...
except CloudFlare.exceptions.CloudFlareAPIError as e:
if len(e) > 0:
sys.stderr.write('api error - more than one error value returned!\n')
for x in e:
sys.stderr.write('api error: %d %s\n' % (x, x))
exit('api error: %d %s' % (e, e))
...
Included example code
---------------------

Expand Down
4 changes: 4 additions & 0 deletions cli4/cli4.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ def cli4(args):
else:
pass
except CloudFlare.exceptions.CloudFlareAPIError as e:
if len(e) > 0:
# more than one error returned by the API
for x in e:
sys.stderr.write('cli4: /%s - %d %s\n' % (command, x, x))
exit('cli4: /%s - %d %s' % (command, e, e))
except Exception as e:
exit('cli4: /%s - %s - api error' % (command, e))
Expand Down

0 comments on commit 3650b3e

Please sign in to comment.