fix: safe json conversion (#3148)

This commit is contained in:
Vlad Stan 2025-05-13 12:51:58 +03:00 committed by GitHub
parent ceb8203353
commit f74fcea35b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -648,9 +648,9 @@ def model_to_dict(model: BaseModel) -> dict:
def dict_to_submodel(model: type[TModel], value: dict | str) -> TModel | None:
"""convert a dictionary or JSON string to a Pydantic model"""
if isinstance(value, str):
if value == "null":
if value == "null" or value == "":
return None
_subdict = json.loads(value)
_subdict = _safe_load_json(value)
elif isinstance(value, dict):
_subdict = value
@ -674,7 +674,7 @@ def dict_to_model(_row: dict, model: type[TModel]) -> TModel:
type_ = model.__fields__[key].type_
outertype_ = model.__fields__[key].outer_type_
if get_origin(outertype_) is list:
_items = json.loads(value) if isinstance(value, str) else value
_items = _safe_load_json(value) if isinstance(value, str) else value
_dict[key] = [
dict_to_submodel(type_, v) if issubclass(type_, BaseModel) else v
for v in _items
@ -695,7 +695,7 @@ def dict_to_model(_row: dict, model: type[TModel]) -> TModel:
# TODO: remove this when all sub models are migrated to Pydantic
# NOTE: this is for type dict on BaseModel, (used in Payment class)
if type_ is dict and value:
_dict[key] = json.loads(value)
_dict[key] = _safe_load_json(value)
continue
_dict[key] = value
continue
@ -703,3 +703,12 @@ def dict_to_model(_row: dict, model: type[TModel]) -> TModel:
if isinstance(_model, BaseModel):
_model.__init__(**_dict) # type: ignore
return _model
def _safe_load_json(value: str) -> dict:
try:
return json.loads(value)
except json.JSONDecodeError:
# DB is corrupted if it gets here
logger.error(f"Failed to decode JSON: '{value}'")
return {}