From e4d0ea23012f89046fb232e9ff06f51ca22fd899 Mon Sep 17 00:00:00 2001 From: Max Metz Date: Wed, 4 Sep 2024 12:11:05 +0200 Subject: [PATCH] fixed serialization of marshmallow.ValidationErrors. This was caused by the 'valid_data' containing datetime objects, which were not serializable natively. --- .../BreCal/validators/validation_error.py | 11 +++++++++-- .../tests/validators/test_validation_error.py | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/server/tests/validators/test_validation_error.py diff --git a/src/server/BreCal/validators/validation_error.py b/src/server/BreCal/validators/validation_error.py index cdac103..65ee985 100644 --- a/src/server/BreCal/validators/validation_error.py +++ b/src/server/BreCal/validators/validation_error.py @@ -27,8 +27,15 @@ def create_validation_error_response(ex:ValidationError, status_code:int=400)->t "errors":errors, "valid_data":valid_data } - return (json.dumps(json_response), status_code) + + # 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) + return (serialized_response, status_code) def create_werkzeug_error_response(ex:Forbidden, status_code:int=403)->typing.Tuple[str,int]: - return json.dumps({"message":ex.description}), status_code + # 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) + return serialized_response, status_code diff --git a/src/server/tests/validators/test_validation_error.py b/src/server/tests/validators/test_validation_error.py new file mode 100644 index 0000000..a103919 --- /dev/null +++ b/src/server/tests/validators/test_validation_error.py @@ -0,0 +1,19 @@ +import pytest + +def test_create_validation_error_response_is_serializable(): + from BreCal.stubs.times_full import get_valid_stub_times + from BreCal.schemas import model + from BreCal.validators.validation_error import create_validation_error_response + + content = get_valid_stub_times() + + import datetime + content["operations_end"] = (datetime.datetime.now()-datetime.timedelta(minutes=14)).isoformat() + + content["id"] = 3 + try: + loadedModel = model.TimesSchema().load(data=content, many=False, partial=True) + except Exception as ex: + my_var = ex + create_validation_error_response(ex=ex, status_code=400) # this function initially created errors, as datetime objects were not serializable. Corrected now. + return