Added ErrorHandler for automatic Exception handling
No need for try except for HTTP 500 or 403 error
This commit is contained in:
parent
55dc622e11
commit
b6157f4953
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue