Skip to content

Commit

Permalink
Improve error when conversion fails
Browse files Browse the repository at this point in the history
  • Loading branch information
ihabunek committed Nov 18, 2023
1 parent 05c5bcb commit 59adec3
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion toot/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,21 @@ class Instance:
T = TypeVar("T")


class ConversionError(Exception):
"""Raised when conversion fails from JSON value to data class field."""
def __init__(
self,
data_class: Type,
field_name: str,
field_type: Type,
field_value: str | None,
):
super().__init__(
f"Failed converting field `{data_class.__name__}.{field_name}` " +
f"of type `{field_type.__name__}` from value {field_value!r}"
)


def from_dict(cls: Type[T], data: Dict) -> T:
"""Convert a nested dict into an instance of `cls`."""
# Apply __toot_prepare__ if it exists
Expand All @@ -389,7 +404,8 @@ def _fields():
field_type = _prune_optional(hints[field.name])
default_value = _get_default_value(field)
value = data.get(field.name, default_value)
yield field.name, _convert(field_type, value)
converted = _convert_with_error_handling(cls, field.name, field_type, value)
yield field.name, converted

return cls(**dict(_fields()))

Expand All @@ -404,6 +420,20 @@ def _get_default_value(field):
return None


def _convert_with_error_handling(
data_class: Type,
field_name: str,
field_type: Type,
field_value: str | None
):
try:
return _convert(field_type, field_value)
except ConversionError:
raise
except Exception:
raise ConversionError(data_class, field_name, field_type, field_value)


def _convert(field_type, value):
if value is None:
return None
Expand Down

0 comments on commit 59adec3

Please sign in to comment.