Templating
{self.something}
templating pieces will be interpolated when rendering the exception value.
examples/open-the-pod-bay-doors.py
from dataclasses import dataclass
from documented import Documented, DocumentedError
@dataclass
class PodBayDoorsStillClosed(DocumentedError):
"""
Iβm sorry, {self.user_name}.
Iβm afraid I canβt do that.
"""
user_name: str
class OpenThePodBayDoors(Documented):
"""Open the pod bay doors please, HAL."""
print(OpenThePodBayDoors())
raise PodBayDoorsStillClosed(user_name='Dave')
python
Open the pod bay doors please, HAL.
Traceback (most recent call last):
File "π/open-the-pod-bay-doors.py", line 22, in <module>
raise PodBayDoorsStillClosed(user_name='Dave')
PodBayDoorsStillClosed: Iβm sorry, Dave.
Iβm afraid I canβt do that.
textwrap.dedent()
is applied to the result, thus Python indentation rules do not corrupt the resulting message.-
Template rendering is done using
str.format()
. That function receives the object instance asself
keyword argument.You can also access elements of lists and dicts by index, for example:
{self.countries[US]}
, but I wouldn't recommend that. Use a property instead (see below).
Dynamic content
From template, you can't call methods of the object, but you can access its fields and properties. You might find useful:
@property
- or,
@cached_property
for performance- This function is only available since Python 3.8,
- There is a backport available though.
Dataclasses
Dataclasses are used in this example in order to provide the astronaut's name to the exception in the most convenient way. You can
- opt out of using them if you wish,
- or use
attrs
instead, - or maybe substitute them with pydantic dataclasses.
Error while rendering
If there is an error while rendering the exception then you will see something like this:
examples/not_renderable.py
from documented import DocumentedError
class NotRenderable(DocumentedError):
"""
This exception is not renderable.
{self.no_hope}
"""
@property
def no_hope(self):
return str(1 / 0)
raise NotRenderable()
python
Traceback (most recent call last):
File "π/not_renderable.py", line 16, in <module>
raise NotRenderable()
NotRenderableCould not print a NotRenderable object.
Traceback (most recent call last):
File "/home/runner/work/documented/documented/documented/documented.py", line 22, in __str__
return template.format(self=self)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "π/not_renderable.py", line 13, in no_hope
return str(1 / 0)
~~^~~
ZeroDivisionError: division by zero
: <exception str() failed>