Source code for betty.error

"""
Provide error handling utilities.
"""

import traceback
from typing import TypeVar

from betty.locale.localizable import Localizable
from betty.locale.localizer import Localizer
from typing_extensions import override

_BaseExceptionT = TypeVar("_BaseExceptionT", bound=BaseException)


[docs] def serialize(error: _BaseExceptionT) -> _BaseExceptionT: """ Serialize an exception. This replaces the exception's traceback object with the traceback formatted as a string. """ formatted_traceback = f'\n"""\n{"".join(traceback.format_exception(type(error), error, error.__traceback__))}"""' error.__cause__ = _SerializedTraceback(formatted_traceback) error.__traceback__ = None return error
class _SerializedTraceback(Exception): def __init__(self, formatted_traceback: str): self._formatted_traceback = formatted_traceback def __str__(self) -> str: return self._formatted_traceback
[docs] class UserFacingError(Exception, Localizable): """ A localizable, user-facing error. This type of error is fatal, but fixing it does not require knowledge of Betty's internals or the stack trace leading to the error. It must therefore have an end-user-friendly message, and its stack trace must not be shown. """
[docs] def __init__(self, message: Localizable): from betty.locale.localizer import DEFAULT_LOCALIZER super().__init__( # Provide a default localization so this exception can be displayed like any other. message.localize(DEFAULT_LOCALIZER), ) self._localizable_message = message
def __str__(self) -> str: from betty.locale.localizer import DEFAULT_LOCALIZER return self.localize(DEFAULT_LOCALIZER)
[docs] @override def localize(self, localizer: Localizer) -> str: return self._localizable_message.localize(localizer)