mirror of https://github.com/mitsuhiko/flask.git
Armin Ronacher
12 years ago
2 changed files with 64 additions and 0 deletions
@ -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) |
Loading…
Reference in new issue