diff --git a/src/server/BreCal/api/berths.py b/src/server/BreCal/api/berths.py index ba8f4ff..57d960e 100644 --- a/src/server/BreCal/api/berths.py +++ b/src/server/BreCal/api/berths.py @@ -3,6 +3,7 @@ from webargs.flaskparser import parser from .. import impl from ..services.auth_guard import auth_guard import json +from BreCal.validators.validation_error import create_dynamic_exception_response bp = Blueprint('berths', __name__) @@ -15,4 +16,4 @@ def GetBerths(): token = request.headers.get('Authorization') return impl.berths.GetBerths(token) else: - return json.dumps("not authenticated"), 403 + return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated") diff --git a/src/server/BreCal/api/history.py b/src/server/BreCal/api/history.py index c1fe5ad..1cf99e4 100644 --- a/src/server/BreCal/api/history.py +++ b/src/server/BreCal/api/history.py @@ -2,20 +2,21 @@ from flask import Blueprint, request from .. import impl from ..services.auth_guard import auth_guard import json +from BreCal.validators.validation_error import create_dynamic_exception_response bp = Blueprint('history', __name__) @bp.route('/history', methods=['get']) @auth_guard() # no restriction by role -def GetParticipant(): +def GetHistory(): if 'Authorization' in request.headers: token = request.headers.get('Authorization') options = {} if not 'shipcall_id' in request.args: - return json.dumps("missing parameter"), 400 + 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 json.dumps("not authenticated"), 403 + return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated") diff --git a/src/server/BreCal/api/notifications.py b/src/server/BreCal/api/notifications.py index 48a2a44..b68a75f 100644 --- a/src/server/BreCal/api/notifications.py +++ b/src/server/BreCal/api/notifications.py @@ -3,6 +3,7 @@ from .. import impl from ..services.auth_guard import auth_guard import logging import json +from BreCal.validators.validation_error import create_dynamic_exception_response bp = Blueprint('notifications', __name__) @@ -16,4 +17,4 @@ def GetNotifications(): return impl.notifications.GetNotifications(options) else: logging.warning("attempt to load notifications without shipcall id") - return json.dumps("missing argument"), 400 \ No newline at end of file + return create_dynamic_exception_response(ex=None, status_code=400, message="missing argument: shipcall_id") diff --git a/src/server/BreCal/api/participant.py b/src/server/BreCal/api/participant.py index 65887f9..53a369f 100644 --- a/src/server/BreCal/api/participant.py +++ b/src/server/BreCal/api/participant.py @@ -2,6 +2,7 @@ from flask import Blueprint, request from .. import impl from ..services.auth_guard import auth_guard import json +from BreCal.validators.validation_error import create_dynamic_exception_response bp = Blueprint('participants', __name__) @@ -15,5 +16,5 @@ def GetParticipant(): options["user_id"] = request.args.get("user_id") return impl.participant.GetParticipant(options) else: - return json.dumps("not authenticated"), 403 + return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated") diff --git a/src/server/BreCal/api/shipcalls.py b/src/server/BreCal/api/shipcalls.py index e6ac854..743c85b 100644 --- a/src/server/BreCal/api/shipcalls.py +++ b/src/server/BreCal/api/shipcalls.py @@ -7,7 +7,7 @@ from ..services.auth_guard import auth_guard, check_jwt from BreCal.validators.input_validation import validate_posted_shipcall_data, check_if_user_is_bsmd_type from BreCal.validators.input_validation_shipcall import InputValidationShipcall from BreCal.database.sql_handler import execute_sql_query_standalone -from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response +from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response, create_dynamic_exception_response from . import verify_if_request_is_json import logging @@ -37,7 +37,7 @@ def GetShipcalls(): return impl.shipcalls.GetShipcalls(options) else: - return json.dumps("not authenticated"), 403 + return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated") @bp.route('/shipcalls', methods=['post']) @@ -65,7 +65,7 @@ def PostShipcalls(): logging.error(ex) logging.error(traceback.format_exc()) print(ex) - return json.dumps("bad format"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format") return impl.shipcalls.PostShipcalls(loadedModel) @@ -99,6 +99,6 @@ def PutShipcalls(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps("bad format"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format") return impl.shipcalls.PutShipcalls(loadedModel) diff --git a/src/server/BreCal/api/ships.py b/src/server/BreCal/api/ships.py index 9f0c43e..9237502 100644 --- a/src/server/BreCal/api/ships.py +++ b/src/server/BreCal/api/ships.py @@ -6,7 +6,7 @@ from ..schemas import model import json import logging from . import verify_if_request_is_json -from BreCal.validators.validation_error import create_validation_error_response +from BreCal.validators.validation_error import create_validation_error_response, create_dynamic_exception_response from BreCal.validators.input_validation import check_if_user_is_bsmd_type from BreCal.validators.input_validation_ship import InputValidationShip @@ -21,7 +21,7 @@ def GetShips(): token = request.headers.get('Authorization') return impl.ships.GetShips(token) else: - return json.dumps("not authenticated"), 403 + return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated") @bp.route('/ships', methods=['post']) @@ -54,7 +54,7 @@ def PostShip(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps(repr(ex)), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message=None) return impl.ships.PostShip(loadedModel) @@ -83,7 +83,7 @@ def PutShip(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps(repr(ex)), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message=None) return impl.ships.PutShip(loadedModel) @@ -103,7 +103,7 @@ def DeleteShip(): options = {} options["id"] = request.args.get("id") else: - return json.dumps("no id provided"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="no id provided") # validate the request data & user permissions InputValidationShip.evaluate_delete_data(user_data, ship_id) @@ -116,6 +116,6 @@ def DeleteShip(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps(repr(ex)), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message=None) return impl.ships.DeleteShip(options) diff --git a/src/server/BreCal/api/times.py b/src/server/BreCal/api/times.py index 65b18ed..5bf3626 100644 --- a/src/server/BreCal/api/times.py +++ b/src/server/BreCal/api/times.py @@ -7,7 +7,7 @@ import logging from marshmallow import ValidationError from BreCal.validators.input_validation_times import InputValidationTimes from . import verify_if_request_is_json -from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response +from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response, create_dynamic_exception_response bp = Blueprint('times', __name__) @@ -50,7 +50,7 @@ def PostTimes(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps("bad format"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format") return impl.times.PostTimes(loadedModel) @@ -79,7 +79,7 @@ def PutTimes(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps("bad format"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format") return impl.times.PutTimes(loadedModel) @@ -102,7 +102,7 @@ def DeleteTimes(): return impl.times.DeleteTimes(options) else: logging.warning("Times delete missing id argument") - return json.dumps("missing argument"), 400 + return create_dynamic_exception_response(ex=None, status_code=400, message="missing argument: id") except ValidationError as ex: logging.error(ex) @@ -112,4 +112,4 @@ def DeleteTimes(): except Exception as ex: logging.error(ex) print(ex) - return json.dumps("bad format"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format") diff --git a/src/server/BreCal/api/user.py b/src/server/BreCal/api/user.py index 6416704..86b992b 100644 --- a/src/server/BreCal/api/user.py +++ b/src/server/BreCal/api/user.py @@ -6,6 +6,7 @@ import json import logging from marshmallow import ValidationError from . import verify_if_request_is_json +from BreCal.validators.validation_error import create_dynamic_exception_response, create_validation_error_response bp = Blueprint('user', __name__) @@ -22,12 +23,12 @@ def PutUser(): except ValidationError as ex: logging.error(ex) print(ex) - return json.dumps(f"bad format. \nError Messages: {ex.messages}. \nValid Data: {ex.valid_data}"), 400 + return create_validation_error_response(ex=ex, status_code=400) except Exception as ex: logging.error(ex) print(ex) - return json.dumps("bad format"), 400 + return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format") return impl.user.PutUser(loadedModel) diff --git a/src/server/BreCal/validators/validation_error.py b/src/server/BreCal/validators/validation_error.py index bdc06fd..b9b2059 100644 --- a/src/server/BreCal/validators/validation_error.py +++ b/src/server/BreCal/validators/validation_error.py @@ -6,6 +6,14 @@ import werkzeug from werkzeug.exceptions import Forbidden +def create_default_error_format(error_description): + json_response = { + "message":f"{error_description}", + "errors":[], + "valid_data":{} + } + return json_response + def create_validation_error_response(ex:ValidationError, status_code:int=400)->typing.Tuple[str,int]: # generate an overview the errors @@ -39,11 +47,11 @@ def create_validation_error_response(ex:ValidationError, status_code:int=400)->t valid_data = ex.valid_data - json_response = { - "message":"ValidationError", + json_response = create_default_error_format(error_description="ValidationError") + json_response.update({ "errors":errors, "valid_data":valid_data - } + }) # json.dumps with default=str automatically converts non-serializable values to strings. Hence, datetime objects (which are not) # natively serializable are properly serialized. @@ -53,6 +61,13 @@ def create_validation_error_response(ex:ValidationError, status_code:int=400)->t def create_werkzeug_error_response(ex:Forbidden, status_code:int=403)->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. - serialized_response = json.dumps({"message":ex.description}, default=str) + json_response = create_default_error_format(error_description=ex.description) + serialized_response = json.dumps(json_response, default=str) return serialized_response, status_code +def create_dynamic_exception_response(ex, status_code:int=400, message:typing.Optional[str]=None): + 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) + return (serialized_response, status_code)