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 import pkg_resources
from flask import Flask from flask import Flask
from pathlib import Path from pathlib import Path
from flask.json import JSONEncoder, jsonify
from flask_cors import CORS from flask_cors import CORS
from logging.config import dictConfig from logging.config import dictConfig
from werkzeug.exceptions import HTTPException
from werkzeug.local import LocalProxy from werkzeug.local import LocalProxy
_module_path = Path(__file__).parent _module_path = Path(__file__).parent
@ -21,8 +25,27 @@ with (_module_path / 'logging.yml').open(mode='rb') as file:
logging.config.dictConfig(config) 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(): def create_app():
app = Flask(__name__) app = Flask(__name__)
app.json_encoder = CustomJSONEncoder
CORS(app) CORS(app)
with app.app_context(): with app.app_context():
@ -49,4 +72,13 @@ def create_app():
logger.info('Loaded plugin > %s <', entry_point.name) logger.info('Loaded plugin > %s <', entry_point.name)
app.register_blueprint(entry_point.load()()) 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 return app

View File

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

View File

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