Browse Source

Added documentation on API error handlers

pull/764/head
Armin Ronacher 12 years ago
parent
commit
f9f8180f15
  1. 63
      docs/patterns/apierrors.rst
  2. 1
      docs/patterns/index.rst

63
docs/patterns/apierrors.rst

@ -0,0 +1,63 @@
Implementing API Exceptions
===========================
It's very common to implement RESTful APIs on top of Flask. One of the
first thing that developers run into is the realization that the builtin
exceptions are not expressive enough for APIs and that the content type of
``text/html`` they are emitting is not very useful for API consumers.
The better solution than using ``abort`` to signal errors for invalid API
usage is to implement your own exception type and install an error handler
for it that produces the errors in the format the user is expecting.
Simple Exception Class
----------------------
The basic idea is to introduce a new exception that can take a proper
human readable message, a status code for the error and some optional
payload to give more context for the error.
This is a simple example::
from flask import jsonfiy
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
A view can now raise that exception with an error message. Additionally
some extra payload can be provided as a dictionary through the `payload`
parameter.
Registering an Error Handler
----------------------------
At that point views can raise that error, but it would immediately result
in an internal server error. The reason for this is that there is no
handler registered for this error class. That however is easy to add::
@app.errorhandler(InvalidAPIUsage)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
Usage in Views
--------------
Here is how a view can use that functionality::
@app.route('/foo')
def get_foo():
raise InvalidUsage('This view is gone', status_code=410)

1
docs/patterns/index.rst

@ -19,6 +19,7 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_.
packages packages
appfactories appfactories
appdispatch appdispatch
apierrors
urlprocessors urlprocessors
distribute distribute
fabric fabric

Loading…
Cancel
Save