-
-
Notifications
You must be signed in to change notification settings - Fork 133
Description
- cattrs version: 22.1.0
- Python version: 3.10.3
- Operating System: Windows 11
Description
When I structure a raw dictionary into a data class, if there's one or more problems, I get an exception (which apparently can be an exception group, using the backport of a new Python 3.11 feature). The raw traceback of the exception is pretty user-unfriendly.
How do I get the details of what failed, in a form that I can use to report to the end user as an error report showing "user facing" terminology, not technical details?
What I Did
>>> cattrs.structure(["a", "b"], list[int])
+ Exception Group Traceback (most recent call last):
| File "<stdin>", line 1, in <module>
| File "C:\Work\Projects\wheeliebin\.venv\lib\site-packages\cattrs\converters.py", line 281, in structure
| return self._structure_func.dispatch(cl)(obj, cl)
| File "C:\Work\Projects\wheeliebin\.venv\lib\site-packages\cattrs\converters.py", line 470, in _structure_list
| raise IterableValidationError(
| cattrs.errors.IterableValidationError: While structuring list[int] (2 sub-exceptions)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "C:\Work\Projects\wheeliebin\.venv\lib\site-packages\cattrs\converters.py", line 463, in _structure_list
| res.append(handler(e, elem_type))
| File "C:\Work\Projects\wheeliebin\.venv\lib\site-packages\cattrs\converters.py", line 380, in _structure_call
| return cl(obj)
| ValueError: invalid literal for int() with base 10: 'a'
| Structuring list[int] @ index 0
+---------------- 2 ----------------
| Traceback (most recent call last):
| File "C:\Work\Projects\wheeliebin\.venv\lib\site-packages\cattrs\converters.py", line 463, in _structure_list
| res.append(handler(e, elem_type))
| File "C:\Work\Projects\wheeliebin\.venv\lib\site-packages\cattrs\converters.py", line 380, in _structure_call
| return cl(obj)
| ValueError: invalid literal for int() with base 10: 'b'
| Structuring list[int] @ index 1
+------------------------------------
>>> try:
... cattrs.structure(["a", "b"], list[int])
... except Exception as exc:
... # Not sure what to do here...What I'd like to be able to do is get the two ValueError exceptions, as well as where they happened (list[int] @ index 1). If I simply print exc, it returns While structuring list[int] (2 sub-exceptions), which is user-friendly, but omits the information needed to tell the user how to fix the issue.
With a bit of digging, it seems as if I can do something like
for x in exc.exceptions:
print(f"{x}: {x.__note__}")But it's possible to get nested exception groups, so this is incomplete. And __note__ seems to be a string which I can't introspect to produce output in a different format. The only way I can see of having full control over how any issues are reported, is to pre-validate the data structure, at which point I might as well write my own structuring code at the same time...
Am I missing something here, or am I trying to use the library in a way that wasn't intended? (My use case is extremely close to user input validation, it's just that the user input is in TOML, which I can parse easily with a library, but in doing so I defer all the validation of data structures, so my "unstructured data" is actually error-prone user input in all but name...)