Source code for zensols.util.fail

"""General utility classes to measuring time it takes to do work, to logging
and fork/exec operations.

"""
__author__ = 'Paul Landes'

from typing import Dict, Tuple, Any, Type
from dataclasses import dataclass, field
import sys
import traceback
from collections import OrderedDict
from io import StringIO, TextIOBase


[docs] class APIError(Exception): """Base exception from which almost all library raised errors extend. """ pass
[docs] @dataclass class Failure(object): """Contains information for failures as caught exceptions used by programatic methods. """ exception: Exception = field(default=None) """The exception that was generated.""" thrower: Any = field(default=None) """The instance of the class that is throwing the exception.""" traceback: traceback = field(default=None, repr=False) """The stack trace.""" message: str = field(default=None) """A high level explaination of what went wrong""" def __post_init__(self): self._exc_info: Tuple[Type[Exception], Exception, traceback] = \ sys.exc_info() if self.exception is None: self.exception: Exception = self._exc_info[1] if self.traceback is None: self.traceback: traceback = self._exc_info[2] self._traceback_str: str = None def _print_stack(self, writer: TextIOBase = sys.stdout): """Print the stack trace of the exception that caused the failure.""" traceback.print_exception(*self._exc_info, file=writer) @property def traceback_str(self) -> str: """The stack trace as a string. :see :meth:`print_stack` """ if self._traceback_str is None: sio = StringIO() self._print_stack(writer=sio) self._traceback_str = sio.getvalue() return self._traceback_str
[docs] def print_stack(self, writer: TextIOBase = sys.stdout): """Print the stack trace of the exception that caused the failure.""" writer.write(self.traceback_str)
[docs] def rethrow(self): """Raises :obj:`exception`.""" raise self.exception
[docs] def write(self, depth: int = 0, writer: TextIOBase = sys.stdout): """Write the contents of this instance to ``writer`` using indention ``depth``. :param depth: the starting indentation depth :param writer: the writer to dump the content of this writable """ sp = ' ' * (2 * depth) writer.write(f'{sp}{self.message}:\n') self.print_stack(writer)
[docs] def asdict(self) -> Dict[str, Any]: """Return the content of the object as a dictionary.""" return OrderedDict( [['message', self.message], ['exception', self.exception], ['trace', self.traceback_str]])
def __getstate__(self) -> Dict[str, Any]: self.traceback_str state = self.__dict__ state['thrower'] = None state['traceback'] = None state['_exc_info'] = None return state def __setstate__(self, state: Dict[str, Any]): self.__dict__ = state def __str__(self) -> str: msg: str = str(self.exception) if self.message is None else self.message return 'no information' if msg is None else msg def __repr__(self) -> str: msg: str = str(self) return str(f'{type(self.exception).__name__}: {msg}')