Skip to content

Commit

Permalink
Add API usage exception and handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Rudi Giesler committed Mar 23, 2015
1 parent dd1ace7 commit 4500d2a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
16 changes: 16 additions & 0 deletions vumi_twilio_api/tests/test_twilio_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ def test_root_json(self):
content = yield response.json()
self.assertEqual(content, {})

@inlineCallbacks
def test_root_invalid_format(self):
response = yield self._server_request('.foo')
self.assertEqual(
response.headers.getRawHeaders('content-type'),
['application/xml'])
self.assertEqual(response.code, 400)
content = yield response.content()
root = ET.fromstring(content)
[error_message, error_type] = sorted(root, key=lambda c: c.tag)
self.assertEqual(error_message.tag, 'error_message')
self.assertEqual(
error_message.text, "'foo' is not a valid request format")
self.assertEqual(error_type.tag, 'error_type')
self.assertEqual(error_type.text, 'UsageError')


class TestServerFormatting(TestCase):

Expand Down
22 changes: 21 additions & 1 deletion vumi_twilio_api/twilio_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ def teardown_application(self):
yield self.webserver.loseConnection()


class TwilioAPIUsageException(Exception):
"""Called when in incorrect query is sent to the API"""
def __init__(self, message, format_='xml'):
super(TwilioAPIUsageException, self).__init__(message)
self.format_ = format_


class TwilioAPIServer(object):
app = Klein()

Expand All @@ -60,10 +67,23 @@ def format_json(dct):
def _format_response(self, request, dct, format_):
format_ = str(format_.lstrip('.').lower())
func = getattr(
TwilioAPIServer, 'format_' + format_, TwilioAPIServer.format_xml)
TwilioAPIServer, 'format_' + format_, None)
if not func:
raise TwilioAPIUsageException(
'%r is not a valid request format' % format_)
request.setHeader('Content-Type', 'application/%s' % format_)
return func(dct)

@app.handle_errors(TwilioAPIUsageException)
def usage_exception(self, request, failure):
request.setResponseCode(400)
return self._format_response(
request, {
'error_type': 'UsageError',
'error_message': failure.value.message
},
failure.value.format_)

@app.route('/', defaults={'format_': 'xml'}, methods=['GET'])
@app.route('/<string:format_>', methods=['GET'])
def root(self, request, format_):
Expand Down

0 comments on commit 4500d2a

Please sign in to comment.