Add decorator catch_etiquette_exception.

To reduce the number of 500 errors and provide 400 instead.
This commit is contained in:
voussoir 2018-01-09 21:21:15 -08:00
parent b5902ba4f1
commit fe88cdc413
2 changed files with 44 additions and 57 deletions

View file

@ -2,9 +2,30 @@ import flask
from flask import request from flask import request
import functools import functools
import etiquette
from . import jsonify from . import jsonify
def catch_etiquette_exception(function):
'''
If an EtiquetteException is raised, automatically catch it and convert it
into a response so that the user isn't receiving error 500.
'''
@functools.wraps(function)
def wrapped(*args, **kwargs):
try:
return function(*args, **kwargs)
except etiquette.exceptions.EtiquetteException as e:
if isinstance(e, etiquette.exceptions.NoSuch):
status = 404
else:
status = 400
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=status)
flask.abort(response)
return wrapped
def required_fields(fields, forbid_whitespace=False): def required_fields(fields, forbid_whitespace=False):
''' '''
Declare that the endpoint requires certain POST body fields. Without them, Declare that the endpoint requires certain POST body fields. Without them,

View file

@ -355,33 +355,22 @@ def get_tags_core(specific_tag=None):
tags.sort(key=lambda x: x.qualified_name()) tags.sort(key=lambda x: x.qualified_name())
return tags return tags
@decorators.catch_etiquette_exception
def post_photo_add_remove_tag_core(photo_id, tagname, add_or_remove): def post_photo_add_remove_tag_core(photo_id, tagname, add_or_remove):
photo = P_photo(photo_id, response_type='json') photo = P_photo(photo_id, response_type='json')
tag = P_tag(tagname, response_type='json') tag = P_tag(tagname, response_type='json')
try:
if add_or_remove == 'add': if add_or_remove == 'add':
photo.add_tag(tag) photo.add_tag(tag)
elif add_or_remove == 'remove': elif add_or_remove == 'remove':
photo.remove_tag(tag) photo.remove_tag(tag)
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=400)
flask.abort(response)
response = {'tagname': tag.name} response = {'tagname': tag.name}
return jsonify.make_json_response(response) return jsonify.make_json_response(response)
@decorators.catch_etiquette_exception
def post_tag_create_delete_core(tagname, function): def post_tag_create_delete_core(tagname, function):
try: return jsonify.make_json_response(function(tagname))
response = function(tagname)
status = 200
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
status = 400
#print(response)
return jsonify.make_json_response(response, status=status)
#################################################################################################### ####################################################################################################
@ -464,6 +453,7 @@ def get_album_zip(album_id):
return flask.Response(streamed_zip, headers=outgoing_headers) return flask.Response(streamed_zip, headers=outgoing_headers)
@site.route('/album/<album_id>/add_tag', methods=['POST']) @site.route('/album/<album_id>/add_tag', methods=['POST'])
@decorators.catch_etiquette_exception
@session_manager.give_token @session_manager.give_token
def post_album_add_tag(album_id): def post_album_add_tag(album_id):
''' '''
@ -487,6 +477,7 @@ def post_album_add_tag(album_id):
@site.route('/album/<album_id>/add_photo', methods=['POST']) @site.route('/album/<album_id>/add_photo', methods=['POST'])
@session_manager.give_token @session_manager.give_token
@decorators.catch_etiquette_exception
@decorators.required_fields(['photo_id'], forbid_whitespace=True) @decorators.required_fields(['photo_id'], forbid_whitespace=True)
def post_album_add_photo(album_id): def post_album_add_photo(album_id):
''' '''
@ -504,6 +495,7 @@ def post_album_add_photo(album_id):
@site.route('/album/<album_id>/remove_photo', methods=['POST']) @site.route('/album/<album_id>/remove_photo', methods=['POST'])
@session_manager.give_token @session_manager.give_token
@decorators.catch_etiquette_exception
@decorators.required_fields(['photo_id'], forbid_whitespace=True) @decorators.required_fields(['photo_id'], forbid_whitespace=True)
def post_album_remove_photo(album_id): def post_album_remove_photo(album_id):
''' '''
@ -521,6 +513,7 @@ def post_album_remove_photo(album_id):
@site.route('/album/<album_id>/edit', methods=['POST']) @site.route('/album/<album_id>/edit', methods=['POST'])
@session_manager.give_token @session_manager.give_token
@decorators.catch_etiquette_exception
def post_album_edit(album_id): def post_album_edit(album_id):
''' '''
Edit the title / description. Edit the title / description.
@ -529,12 +522,7 @@ def post_album_edit(album_id):
title = request.form.get('title', None) title = request.form.get('title', None)
description = request.form.get('description', None) description = request.form.get('description', None)
try:
album.edit(title=title, description=description) album.edit(title=title, description=description)
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=400)
flask.abort(response)
response = etiquette.jsonify.album(album, minimal=True) response = etiquette.jsonify.album(album, minimal=True)
return jsonify.make_json_response(response) return jsonify.make_json_response(response)
@ -554,6 +542,7 @@ def get_albums_json():
return jsonify.make_json_response(albums) return jsonify.make_json_response(albums)
@site.route('/albums/create_album', methods=['POST']) @site.route('/albums/create_album', methods=['POST'])
@decorators.catch_etiquette_exception
def post_albums_create(): def post_albums_create():
title = request.form.get('title', None) title = request.form.get('title', None)
description = request.form.get('description', None) description = request.form.get('description', None)
@ -561,12 +550,7 @@ def post_albums_create():
if parent is not None: if parent is not None:
parent = P_album(parent) parent = P_album(parent)
try:
album = P.new_album(title=title, description=description) album = P.new_album(title=title, description=description)
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=400)
flask.abort(response)
if parent is not None: if parent is not None:
parent.add_child(album) parent.add_child(album)
response = etiquette.jsonify.album(album, minimal=False) response = etiquette.jsonify.album(album, minimal=False)
@ -582,6 +566,7 @@ def get_bookmark_json(bookmarkid):
@site.route('/bookmark/<bookmarkid>/edit', methods=['POST']) @site.route('/bookmark/<bookmarkid>/edit', methods=['POST'])
@session_manager.give_token @session_manager.give_token
@decorators.catch_etiquette_exception
def post_bookmark_edit(bookmarkid): def post_bookmark_edit(bookmarkid):
bookmark = P_bookmark(bookmarkid) bookmark = P_bookmark(bookmarkid)
# Emptystring is okay for titles, but not for URL. # Emptystring is okay for titles, but not for URL.
@ -607,16 +592,12 @@ def get_bookmarks_json():
return jsonify.make_json_response(bookmarks) return jsonify.make_json_response(bookmarks)
@site.route('/bookmarks/create_bookmark', methods=['POST']) @site.route('/bookmarks/create_bookmark', methods=['POST'])
@decorators.catch_etiquette_exception
@decorators.required_fields(['url'], forbid_whitespace=True) @decorators.required_fields(['url'], forbid_whitespace=True)
def post_bookmarks_create(): def post_bookmarks_create():
url = request.form['url'] url = request.form['url']
title = request.form.get('title', None) title = request.form.get('title', None)
try:
bookmark = P.new_bookmark(url=url, title=title) bookmark = P.new_bookmark(url=url, title=title)
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=400)
flask.abort(response)
response = etiquette.jsonify.bookmark(bookmark) response = etiquette.jsonify.bookmark(bookmark)
response = jsonify.make_json_response(response) response = jsonify.make_json_response(response)
return response return response
@ -721,18 +702,14 @@ def post_photo_add_tag(photo_id):
return post_photo_add_remove_tag_core(photo_id, request.form['tagname'], 'add') return post_photo_add_remove_tag_core(photo_id, request.form['tagname'], 'add')
@site.route('/photo/<photo_id>/refresh_metadata', methods=['POST']) @site.route('/photo/<photo_id>/refresh_metadata', methods=['POST'])
@decorators.catch_etiquette_exception
def post_photo_refresh_metadata(photo_id): def post_photo_refresh_metadata(photo_id):
''' '''
Refresh the file metadata. Refresh the file metadata.
''' '''
P.caches['photo'].remove(photo_id) P.caches['photo'].remove(photo_id)
photo = P_photo(photo_id, response_type='json') photo = P_photo(photo_id, response_type='json')
try:
photo.reload_metadata() photo.reload_metadata()
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=400)
flask.abort(response)
if photo.thumbnail is None: if photo.thumbnail is None:
try: try:
photo.generate_thumbnail() photo.generate_thumbnail()
@ -756,6 +733,7 @@ def get_register():
@site.route('/register', methods=['POST']) @site.route('/register', methods=['POST'])
@session_manager.give_token @session_manager.give_token
@decorators.catch_etiquette_exception
@decorators.required_fields(['username', 'password_1', 'password_2']) @decorators.required_fields(['username', 'password_1', 'password_2'])
def post_register(): def post_register():
if session_manager.get(request): if session_manager.get(request):
@ -774,11 +752,7 @@ def post_register():
} }
return jsonify.make_json_response(response, status=422) return jsonify.make_json_response(response, status=422)
try:
user = P.register_user(username, password_1) user = P.register_user(username, password_1)
except etiquette.exceptions.EtiquetteException as e:
response = etiquette.jsonify.exception(e)
return jsonify.make_json_response(response, status=400)
session = sessions.Session(request, user) session = sessions.Session(request, user)
session_manager.add(session) session_manager.add(session)
@ -858,20 +832,12 @@ def get_tags_json(specific_tag_name=None):
return jsonify.make_json_response(tags) return jsonify.make_json_response(tags)
@site.route('/tag/<specific_tag>/edit', methods=['POST']) @site.route('/tag/<specific_tag>/edit', methods=['POST'])
@decorators.catch_etiquette_exception
def post_tag_edit(specific_tag): def post_tag_edit(specific_tag):
tag = P_tag(specific_tag) tag = P_tag(specific_tag)
name = request.form.get('name', '').strip() name = request.form.get('name', '').strip()
if name: if name:
try:
tag.rename(name, commit=False) tag.rename(name, commit=False)
except etiquette.exceptions.EtiquetteException as e:
if isinstance(e, etiquette.exceptions.NoSuch):
status = 404
else:
status = 400
response = etiquette.jsonify.exception(e)
response = jsonify.make_json_response(response, status=status)
flask.abort(response)
description = request.form.get('description', None) description = request.form.get('description', None)
tag.edit(description=description) tag.edit(description=description)