Added ErrorHandler for automatic Exception handling

No need for try except for HTTP 500 or 403 error
This commit is contained in:
Ferdinand Thiessen 2020-09-03 22:04:28 +02:00
parent 55dc622e11
commit b6157f4953
3 changed files with 42 additions and 12 deletions

View File

@ -9,8 +9,12 @@ import logging
import pkg_resources
from flask import Flask
from pathlib import Path
from flask.json import JSONEncoder, jsonify
from flask_cors import CORS
from logging.config import dictConfig
from werkzeug.exceptions import HTTPException
from werkzeug.local import LocalProxy
_module_path = Path(__file__).parent
@ -21,8 +25,27 @@ with (_module_path / 'logging.yml').open(mode='rb') as file:
logging.config.dictConfig(config)
class CustomJSONEncoder(JSONEncoder):
def default(self, o):
# Check if custom model
try:
return o.serialize()
except AttributeError:
pass
# Check if iterable
try:
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
return JSONEncoder.default(self, o)
def create_app():
app = Flask(__name__)
app.json_encoder = CustomJSONEncoder
CORS(app)
with app.app_context():
@ -49,4 +72,13 @@ def create_app():
logger.info('Loaded plugin > %s <', entry_point.name)
app.register_blueprint(entry_point.load()())
@app.errorhandler(Exception)
def handle_exception(e):
if isinstance(e, HTTPException):
logger.debug(e.description, exc_info=True)
return jsonify({"error": e.name}), e.code
logger.error(str(e), exc_info=True)
return jsonify({"error": "Internal server error occurred"}), 500
return app

View File

@ -1,5 +1,7 @@
from functools import wraps
from flask import request, jsonify
from werkzeug.exceptions import Unauthorized
from flaschengeist import logger
@ -15,15 +17,13 @@ def login_required(**kwargs):
def wrapper(*args, **kwargs):
token = request.headers.get('Token')
logger.debug("token is {{ {} }}".format(token))
access_token = ac_controller.validate_token(token, roles)
logger.debug("accToken is {{ {} }}".format(access_token))
kwargs['accToken'] = access_token
access_token = ac_controller.validate_token(token, request.user_agent, roles)
if access_token:
kwargs['access_token'] = access_token
logger.debug("token {{ {} }} is valid".format(token))
return func(*args, **kwargs)
else:
logger.warning("token {{ {} }} is not valid".format(token))
return jsonify({"error": "error",
"message": "permission denied"}), 401
logger.info("token {{ {} }} is not valid".format(token))
raise Unauthorized
return wrapper
return real_decorator

View File

@ -61,7 +61,7 @@ class User(db.Model):
if 'display_name' in data:
self.display_name = data['display_name']
def default(self):
def serialize(self):
return {
# TODO: username should be UID?
"username": self.uid,
@ -93,10 +93,8 @@ class Group(db.Model):
name = db.Column(db.String(30))
permissions = db.relationship("Permission", secondary=group_permission_association_table)
def toJSON(self):
return {
'name': self.name
}
def serialize(self):
return self.name
class Permission(db.Model):