Exception handling¶
Satella provides a rich functionality to register exception hooks.
Note
Satella does not install a custom faulthandler. Do it yourself.
Writing your own exception handlers¶
To write your own exception handlers, subclass the following class:
-
class
satella.exception_handling.
BaseExceptionHandler
(priority=0)¶ -
handle_exception
(type_: Callable[[type, BaseException, traceback], None], value, traceback: traceback) → Optional[bool]¶ Return True to intercept the exception, so that it won’t be propagated to other handlers.
-
install
() → satella.exception_handling.exception_handlers.BaseExceptionHandler¶ Register this handler to run upon exceptions
-
uninstall
()¶ Unregister this handler to run on exceptions
-
And then instantiate it and call install()
.
If you got a callable of signature [type, BaseException, types.TracebackType] (type, value, traceback) that returns True upon a request to swallow the exception, you can convert it to a Satella exception handler in two ways.
First:
a = FunctionExceptionHandler(exception_handle)
a.install()
Or
@exception_handler
def exception_handle(type, value, traceback) -> bool
...
exception_handle().install()
-
satella.exception_handling.
exception_handler
(priority: int = 0)¶ Convert a callable to an FunctionExceptionHandler. Usage
>>> @exception_handler(priority=-10) >>> def handle_exc(type_, val, traceback): >>> ...
You can use also:
>>> @exception_handler >>> def handle_exc(type_, val, traceback): >>> ...
The default priority is 0. But this way of calling it is not recommended, and will result in a UserWarning.
Returns: ExceptionHandler instance
-
class
satella.exception_handling.
FunctionExceptionHandler
(fun: Callable[[type, BaseException, traceback], Union[Sequence[bool], bool]], priority: int = 0)¶ A exception handler to make callables of given signature into Satella’s exception handlers.
Your exception handler must return a bool, whether to intercept the exception and not propagate it.
-
handle_exception
(type_, value, traceback)¶ Return True to intercept the exception, so that it won’t be propagated to other handlers.
-
Pre-defined exception handlers¶
MemoryErrorExceptionHandler¶
-
class
satella.exception_handling.
MemoryErrorExceptionHandler
(custom_hook: Callable[[type, BaseException, traceback], Union[Sequence[bool], bool]] = <function MemoryErrorExceptionHandler.<lambda>>, kill_pg: bool = False)¶ A handler that terminates the entire process (or process group) is a MemoryError is seen.
custom_hook is an exception callable to implement you own behavior. If it returns True, then MemoryErrorExceptionHandler won’t kill anyone. You can also provide a CallableGroup with gather=True - if any of callables returns True, the process won’t be killed.
Parameters: kill_pg – whether to kill entire process group, if applicable
This exception hook kills the entire process if a MemoryError is spotted, under the rule that it’s better to fail early than admit undefined behaviour.
DumpToFileHandler¶
-
class
satella.exception_handling.
DumpToFileHandler
(human_readables: Iterable[Union[str, TextIO, logging.Logger, Tuple[logging.Logger, int]]], trace_pickles: Iterable[Union[str, BinaryIO]] = None)¶ Write the stack trace to a stream-file.
Note that your file-like objects you throw into that must support only .write() and optionally .flush()
Parameters: - human_readables – iterable of either a file-like objects, or paths where human-readable files will be output. Also a logger can be put here, or a tuple of logger, logging level. Default logging level will be ERROR.
- trace_pickles – iterable of either a file-like objects, or paths where pickles with stack status will be output
Raises: TypeError – invalid stream
A handler that will dump each stack frame of the exception, along with it’s variables, to a file (or stdout/stderr). Two file handles/names are admitted:
- human_readables - where human-readable form of the exception and it’s values will be output
- trace_pickles - where pickled `Traceback`s from the exception will be put.
You can throw there either:
- a str - file of given name will be created and data will be output to it
- a file-like object supporting
write()
(and optionallyflush()
) - data will be output to it - a None - output will be piped to /dev/null
Note that the arguments are lists, so you can specify multiple target sources.