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:
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, TracebackType], 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: ~typing.Callable[[type, BaseException, ~types.TracebackType], ~typing.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[str | TextIO | Logger | Tuple[Logger, int]], trace_pickles: Iterable[str | BinaryIO] | None = 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 ita None - output will be piped to /dev/null
Note that the arguments are lists, so you can specify multiple target sources.