creating default handlers for every kind of Exception in the /api/ routes. Those default functions also create automatic logging with the .warning level. Relocated the .impl-calls into the Try-Exception-blocks, so they are properly logged and avoid system failures.
This commit is contained in:
parent
85973ad848
commit
d2cd233f13
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
from flask import Blueprint, request
|
||||
from webargs.flaskparser import parser
|
||||
from .. import impl
|
||||
@ -12,8 +13,12 @@ bp = Blueprint('berths', __name__)
|
||||
@auth_guard() # no restriction by role
|
||||
def GetBerths():
|
||||
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
return impl.berths.GetBerths(token)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
return impl.berths.GetBerths(token)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
from flask import Blueprint, request
|
||||
from .. import impl
|
||||
from ..services.auth_guard import auth_guard
|
||||
@ -10,13 +11,16 @@ bp = Blueprint('history', __name__)
|
||||
@auth_guard() # no restriction by role
|
||||
def GetHistory():
|
||||
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
options = {}
|
||||
if not 'shipcall_id' in request.args:
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="missing parameter: shipcall_id")
|
||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||
return impl.history.GetHistory(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
options = {}
|
||||
if not 'shipcall_id' in request.args:
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="missing parameter: shipcall_id")
|
||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||
return impl.history.GetHistory(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
@ -11,10 +11,13 @@ bp = Blueprint('notifications', __name__)
|
||||
@bp.route('/notifications', methods=['get'])
|
||||
@auth_guard() # no restriction by role
|
||||
def GetNotifications():
|
||||
if 'shipcall_id' in request.args:
|
||||
options = {}
|
||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||
return impl.notifications.GetNotifications(options)
|
||||
else:
|
||||
logging.warning("attempt to load notifications without shipcall id")
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="missing argument: shipcall_id")
|
||||
try:
|
||||
if 'shipcall_id' in request.args:
|
||||
options = {}
|
||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||
return impl.notifications.GetNotifications(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="missing argument: shipcall_id")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
from flask import Blueprint, request
|
||||
from .. import impl
|
||||
from ..services.auth_guard import auth_guard
|
||||
@ -10,11 +11,14 @@ bp = Blueprint('participants', __name__)
|
||||
@auth_guard() # no restriction by role
|
||||
def GetParticipant():
|
||||
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
options = {}
|
||||
options["user_id"] = request.args.get("user_id")
|
||||
return impl.participant.GetParticipant(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
options = {}
|
||||
options["user_id"] = request.args.get("user_id")
|
||||
return impl.participant.GetParticipant(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
@ -20,24 +20,28 @@ bp = Blueprint('shipcalls', __name__)
|
||||
@bp.route('/shipcalls', methods=['get'])
|
||||
@auth_guard() # no restriction by role
|
||||
def GetShipcalls():
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization') # see impl/login to see the token encoding, which is a JWT token.
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization') # see impl/login to see the token encoding, which is a JWT token.
|
||||
|
||||
"""
|
||||
from BreCal.services.jwt_handler import decode_jwt
|
||||
jwt = token.split('Bearer ')[1] # string key
|
||||
payload = decode_jwt(jwt) # dictionary, which includes 'id' (user id) and 'participant_id'
|
||||
"""
|
||||
from BreCal.services.jwt_handler import decode_jwt
|
||||
jwt = token.split('Bearer ')[1] # string key
|
||||
payload = decode_jwt(jwt) # dictionary, which includes 'id' (user id) and 'participant_id'
|
||||
|
||||
# oneline:
|
||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||
"""
|
||||
options = {}
|
||||
options["participant_id"] = request.args.get("participant_id")
|
||||
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
||||
# oneline:
|
||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||
"""
|
||||
options = {}
|
||||
options["participant_id"] = request.args.get("participant_id")
|
||||
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
||||
|
||||
return impl.shipcalls.GetShipcalls(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
return impl.shipcalls.GetShipcalls(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
|
||||
@bp.route('/shipcalls', methods=['post'])
|
||||
@ -55,20 +59,15 @@ def PostShipcalls():
|
||||
|
||||
# validate the posted shipcall data & the user's authority
|
||||
InputValidationShipcall.evaluate_post_data(user_data, loadedModel, content)
|
||||
return impl.shipcalls.PostShipcalls(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
logging.error(traceback.format_exc())
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||
|
||||
return impl.shipcalls.PostShipcalls(loadedModel)
|
||||
|
||||
|
||||
@bp.route('/shipcalls', methods=['put'])
|
||||
@auth_guard() # no restriction by role
|
||||
@ -85,20 +84,15 @@ def PutShipcalls():
|
||||
|
||||
# validate the PUT shipcall data and the user's authority
|
||||
InputValidationShipcall.evaluate_put_data(user_data, loadedModel, content)
|
||||
return impl.shipcalls.PutShipcalls(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except werkzeug.exceptions.Forbidden as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_werkzeug_error_response(ex=ex, status_code=403)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||
logging.error(traceback.format_exc())
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="bad format")
|
||||
|
||||
return impl.shipcalls.PutShipcalls(loadedModel)
|
||||
|
||||
@ -17,11 +17,15 @@ bp = Blueprint('ships', __name__)
|
||||
@auth_guard() # no restriction by role
|
||||
def GetShips():
|
||||
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
return impl.ships.GetShips(token)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
return impl.ships.GetShips(token)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
|
||||
@bp.route('/ships', methods=['post'])
|
||||
@ -45,19 +49,14 @@ def PostShip():
|
||||
|
||||
# validate the request data & user permissions
|
||||
InputValidationShip.evaluate_post_data(user_data, loadedModel, content)
|
||||
return impl.ships.PostShip(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message=None)
|
||||
|
||||
return impl.ships.PostShip(loadedModel)
|
||||
|
||||
|
||||
@bp.route('/ships', methods=['put'])
|
||||
@auth_guard() # no restriction by role
|
||||
@ -74,18 +73,13 @@ def PutShip():
|
||||
|
||||
# validate the request data & user permissions
|
||||
InputValidationShip.evaluate_put_data(user_data, loadedModel, content)
|
||||
return impl.ships.PutShip(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message=None)
|
||||
|
||||
return impl.ships.PutShip(loadedModel)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
|
||||
@bp.route('/ships', methods=['delete'])
|
||||
@ -107,15 +101,11 @@ def DeleteShip():
|
||||
|
||||
# validate the request data & user permissions
|
||||
InputValidationShip.evaluate_delete_data(user_data, ship_id)
|
||||
return impl.ships.DeleteShip(options)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message=None)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
return impl.ships.DeleteShip(options)
|
||||
|
||||
@ -16,10 +16,13 @@ bp = Blueprint('times', __name__)
|
||||
@auth_guard() # no restriction by role
|
||||
def GetTimes():
|
||||
|
||||
options = {}
|
||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||
try:
|
||||
options = {}
|
||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||
return impl.times.GetTimes(options)
|
||||
|
||||
return impl.times.GetTimes(options)
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
|
||||
|
||||
@bp.route('/times', methods=['post'])
|
||||
@ -41,18 +44,14 @@ def PostTimes():
|
||||
|
||||
# validate the request
|
||||
InputValidationTimes.evaluate_post_data(user_data, loadedModel, content)
|
||||
return impl.times.PostTimes(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||
|
||||
return impl.times.PostTimes(loadedModel)
|
||||
|
||||
|
||||
@bp.route('/times', methods=['put'])
|
||||
@ -70,18 +69,14 @@ def PutTimes():
|
||||
|
||||
# validate the request
|
||||
InputValidationTimes.evaluate_put_data(user_data, loadedModel, content)
|
||||
return impl.times.PutTimes(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||
|
||||
return impl.times.PutTimes(loadedModel)
|
||||
|
||||
|
||||
@bp.route('/times', methods=['delete'])
|
||||
@ -101,15 +96,10 @@ def DeleteTimes():
|
||||
|
||||
return impl.times.DeleteTimes(options)
|
||||
else:
|
||||
logging.warning("Times delete missing id argument")
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="missing argument: id")
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="Times delete missing argument: id")
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||
|
||||
@ -19,16 +19,12 @@ def PutUser():
|
||||
|
||||
content = request.get_json(force=True)
|
||||
loadedModel = model.UserSchema().load(data=content, many=False, partial=True)
|
||||
return impl.user.PutUser(loadedModel)
|
||||
|
||||
except ValidationError as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_validation_error_response(ex=ex, status_code=400)
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||
return create_dynamic_exception_response(ex=None, status_code=400, message="bad format")
|
||||
|
||||
return impl.user.PutUser(loadedModel)
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ def create_default_error_format(error_description):
|
||||
return json_response
|
||||
|
||||
|
||||
def create_validation_error_response(ex:ValidationError, status_code:int=400)->typing.Tuple[str,int]:
|
||||
def create_validation_error_response(ex:ValidationError, status_code:int=400, create_log:bool=True)->typing.Tuple[str,int]:
|
||||
# generate an overview the errors
|
||||
#example:
|
||||
# {'lock_time': ['The provided value must be in the future. Current Time: 2024-09-02 08:23:32.600791, Value: 2024-09-01 08:20:41.853000']}
|
||||
@ -46,8 +46,8 @@ def create_validation_error_response(ex:ValidationError, status_code:int=400)->t
|
||||
# }
|
||||
valid_data = ex.valid_data
|
||||
|
||||
|
||||
json_response = create_default_error_format(error_description="ValidationError")
|
||||
message = "ValidationError"
|
||||
json_response = create_default_error_format(error_description=message)
|
||||
json_response.update({
|
||||
"errors":errors,
|
||||
"valid_data":valid_data
|
||||
@ -56,18 +56,31 @@ def create_validation_error_response(ex:ValidationError, status_code:int=400)->t
|
||||
# json.dumps with default=str automatically converts non-serializable values to strings. Hence, datetime objects (which are not)
|
||||
# natively serializable are properly serialized.
|
||||
serialized_response = json.dumps(json_response, default=str)
|
||||
|
||||
if create_log:
|
||||
logging.warning(ex) if ex is not None else logging.warning(message)
|
||||
print(ex) if ex is not None else print(message)
|
||||
return (serialized_response, status_code)
|
||||
|
||||
def create_werkzeug_error_response(ex:Forbidden, status_code:int=403)->typing.Tuple[str,int]:
|
||||
def create_werkzeug_error_response(ex:Forbidden, status_code:int=403, create_log:bool=True)->typing.Tuple[str,int]:
|
||||
# json.dumps with default=str automatically converts non-serializable values to strings. Hence, datetime objects (which are not)
|
||||
# natively serializable are properly serialized.
|
||||
json_response = create_default_error_format(error_description=ex.description)
|
||||
message = ex.description
|
||||
json_response = create_default_error_format(error_description=message)
|
||||
serialized_response = json.dumps(json_response, default=str)
|
||||
|
||||
if create_log:
|
||||
logging.warning(ex) if ex is not None else logging.warning(message)
|
||||
print(ex) if ex is not None else print(message)
|
||||
return serialized_response, status_code
|
||||
|
||||
def create_dynamic_exception_response(ex, status_code:int=400, message:typing.Optional[str]=None):
|
||||
def create_dynamic_exception_response(ex, status_code:int=400, message:typing.Optional[str]=None, create_log:bool=True):
|
||||
message = repr(ex) if message is None else message
|
||||
json_response = create_default_error_format(error_description=message)
|
||||
|
||||
serialized_response = json.dumps(json_response, default=str)
|
||||
|
||||
if create_log:
|
||||
logging.warning(ex) if ex is not None else logging.warning(message)
|
||||
print(ex) if ex is not None else print(message)
|
||||
return (serialized_response, status_code)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user