caikit.core.exceptions.error_handler

Custom exception and error handling logic.

Attributes

_error_handlers

Classes

ErrorHandler

An error handler that provides reusable error checking methods and also handles logging

Functions

get(log_chan)

Get an error handler associated with a given alog log channel. The same error handler will

Module Contents

caikit.core.exceptions.error_handler._error_handlers: Dict[str, ErrorHandler]
caikit.core.exceptions.error_handler.get(log_chan: logging.Logger | alog.protocols.LoggerProtocol)[source]

Get an error handler associated with a given alog log channel. The same error handler will be returned if this function is called repeatedly with the same log channel.

Args:
name: alog channel

An alog log channel.

Returns:
ErrorHandler: An instance of ErrorHandler associated with log_chan

that can be used to perform various error checks and to raise exceptions while also automatically logging appropriate message on log_chan.

class caikit.core.exceptions.error_handler.ErrorHandler(log_chan: logging.Logger | alog.protocols.LoggerProtocol)[source]

An error handler that provides reusable error checking methods and also handles logging error messages automatically. Calling an error handler directly is equivalent to calling the .log_raise method.

log_chan
_handle_exception_messages(log_code: str, exception: Exception)[source]

Handle number of exception log messages to avoid overflows

log_raise(log_code: str, exception: Exception, root_exception: Exception | None = None) NoReturn[source]

Log an exception with a log code and then re-raise it. Using this instead of simply using the raise keyword with your exceptions will ensure that log message is emitted on the error level for the log channel associated with this handler. This is invaluable for debugging in environments where stack traces are not available.

Args:
log_code (str): A log code with format <COR12345678E> where COR

is a short code for the library (for caikit_core in this example) and where 12345678 is a unique eight-digit identifier (example generation in scripts/cor_log_code) and where E is an error level short-code, one of {‘fatal’: ‘F’, ‘error’: ‘E’, ‘warning’: ‘W’, ‘info’: ‘I’, ‘trace’: ‘T’, ‘debug’: ‘D’}.

exception (Exception): A python exception object or an instance of

any subclass of Exception.

root_exception: Exception (Optional)

A python exception object or an instance of any subclass of Exception which is considered a ‘root’ exception, wrapped by the preceding exception. Done in cases where we’d like to wrap a base exception with a custom exception, preserving the original’s stack-trace

Notes:

The error handler will track the number log messages emitted for a given exception and stop logging after MAX_EXCEPTION_LOG_MESSAGES have been logged for a single instance of an exception. This is to prevent pathological logging, e.g., repeatedly calling log_raise in a recursive function.

__call__
type_check(log_code: str, *types: Type, allow_none: bool = False, **variables: object) None[source]

Check for acceptable types for a given object. If the type check fails, a log message will be emitted at the error level on the log channel associated with this handler and a TypeError exception will be raised with an appropriate message. This check should be used to check for appropriate variable types. For example, to verify that an argument passed to a function that expects a string is actually an instance of a string.

Args:
log_code (str): A log code with format <COR90063501E> where COR

is a short code for the library (for caikit_core in this example) and where 90063501 is a unique eight-digit identifier (example generation in scripts/cor_log_code) and where E is an error level short-code, one of {‘fatal’: ‘F’, ‘error’: ‘E’, ‘warning’: ‘W’, ‘info’: ‘I’, ‘trace’: ‘T’, ‘debug’: ‘D’}.

*types (type or None): Variadic arguments containing all acceptable

types for variables. If any values of variable are not any of *types then a log message will be emitted and a TypeError will be raised. Multiple types may be specified as separate arguments. If no types are specified, then a RuntimeError will be raised.

allow_none (bool): If True then the values of variables are

allowed to take on the value of None without causing the type check to fail. If False (default) then None values will cause the type check to fail.

**variables (object): Variadic keyword arguments to be examined for

acceptable type. The name of the variable is used in log and error messages while its value is actually check against types. Multiple keyword variables may be specified. If no variables are specified, then a RuntimeError will be raised.

Examples:

# this will raise a TypeError because foo is not None or a list or tuple > error.type_check(‘<COR99962332E>’, None, list, tuple, foo=’hello world’)

# this type check verifies that foo and bar are both strings > error.type_check(‘<COR03761101E>’, str, foo=foo, bar=bar)

type_check_all(log_code: str, *types: Type, allow_none: bool = False, **variables: Iterable[object]) None[source]

This type check is similar to .type_check except that it verifies that each variable in **variables is either a list or a tuple and then checks that all of the items they contain are instances of a type in *types. If allow_none is set to True, then the variable is allowed to be None, but the items in the list or tuple are not.

Examples:

# this type check will verify that foo is a list or tuple containing only `int`s > foo = (1, 2, 3) > error.type_check(‘<COR50993928E>’, int, foo=’hello world’)

# this type check allows foo to be None > error.type_check(‘<COR79540602E>’, None, foo=None)

# this type check fails because foo contains None > error.type_check(‘<COR87797257E>’, None, int, foo=(1, 2, None, 3, 4))

# this type check fails because bar contains a str # but not for any other reason > foo = [1, 2, 3] > bar = [4, 5, ‘x’] > baz = None > error.type_check(‘<COR40818868E>’, None, int, foo=foo, bar=bar, baz=None)

subclass_check(log_code: str, child_class: Type, *parent_classes: Type, allow_none: bool = False) None[source]

Check that the given child classes are valid types and that they derive from the given set of parent classes [issubclass(x, (y, z))]. If the subclass check fails, a log message will be emitted at the error level on the log channel associated with this handler and a TypeError exception will be raised with an appropriate message. This check should be used to check that a given class meets the interface of a parent class. For example, to verify that a class handle is a valid ModuleBase subclass.

Args:
log_code (str): A log code with format <COR90063501E> where COR

is a short code for the library (for caikit_core in this example) and where 90063501 is a unique eight-digit identifier and where E is an error level short-code, one of {‘fatal’: ‘F’, ‘error’: ‘E’, ‘warning’: ‘W’, ‘info’: ‘I’, ‘trace’: ‘T’, ‘debug’: ‘D’}.

child_class (Any): The class to be examined for acceptable class

inheritance.

*parent_classes (type): Variadic arguments containing all acceptable

parent types for child_classes. If any values of child_classes are not a valid type derived from one of *parent_classes then a log message will be emitted and a TypeError will be raised. Multiple parent_classes may be specified as separate arguments. If no parent_classes are specified, then a RuntimeError will be raised.

allow_none (bool): If True then the values of child_classes are

allowed to take on the value of None without causing the subclass check to fail. If False (default) then None values will cause the subclass check to fail.

Examples:

# this will raise a TypeError because Foo is not None or # derived from Bar > class Bar: pass > class Foo: pass > error.subclass_check(‘<COR99962332E>’, Bar, Foo=Foo)

# this type check verifies that foo and bar are both strings > error.type_check(‘<COR03761101E>’, str, foo=foo, bar=bar)

value_check(log_code: str, condition: bool, *args: object) None[source]

Check for acceptable values for a given object. If this check fails, a log message will be emitted at the error level on the log channel associated with this handler and a ValueError exception will be raised with an appropriate message. This check should be used for checking for appropriate values for variable instances. For example, to check that a numerical value has an appropriate range.

Args:
log_code (str): A log code with format <COR55705215E> where COR

is a short code for the library (for caikit_core in this example) and where 55705215 is a unique eight-digit identifier (example generation in scripts/cor_log_code) and where E is an error level short-code, one of {‘fatal’: ‘F’, ‘error’: ‘E’, ‘warning’: ‘W’, ‘info’: ‘I’, ‘trace’: ‘T’, ‘debug’: ‘D’}.

condition (bool): A boolean value that should describe if this check

passes True or fails False. Upon calling this function, this is typically provided as an expression, e.g., 0 < variable < 1.

*args: A variable set of arguments describing the value check that failed. If no

args are provided then an empty msg string is assumed and no additional information will be provided, otherwise the first argument will be treated as ‘msg’ argument. Note that string interpolation can be lazily performed on msg using {} format syntax by passing additional arguments. This is the preferred method for performing string interpolation on msg so that it is only done if an error condition is encountered.

file_check(log_code: str, *file_paths: _typeshed.FileDescriptorOrPath) None[source]

Check to see if one or more file paths exist and are regular files. If any do not exist or are not files, then a log message will be emitted on the log channel associated with this error handler and a FileNotFoundError will be raised with an appropriate error message.

Args:
log_code (str): A log code with format <COR73692990E> where COR

is a short code for the library (for caikit_core in this example) and where 55705215 is a unique eight-digit identifier (example generation in scripts/cor_log_code) and where E is an error level short-code, one of {‘fatal’: ‘F’, ‘error’: ‘E’, ‘warning’: ‘W’, ‘info’: ‘I’, ‘trace’: ‘T’, ‘debug’: ‘D’}.

*file_paths (FileDescriptorOrPath): Variadic argument containing strings

specifying the file paths to check. If any of these file paths does not exist or is not a regular file, then a log message will be emitted and a FileNotFoundError will be raised.

dir_check(log_code: str, *dir_paths: _typeshed.FileDescriptorOrPath) None[source]

Check to see if one or more directory paths exist and are, in fact, directories. If any do not exist then a FileNotFoundError will be raised and if they are not directories then a NotADirectoryError will be raised. In either case, a log message will be emitted on the log channel associated with this error handler.

Args:
log_code (str): A log code with format <COR63462828E> where COR

is a short code for the library (for caikit_core in this example) and where 55705215 is a unique eight-digit identifier (example generation in scripts/cor_log_code) and where E is an error level short-code, one of {‘fatal’: ‘F’, ‘error’: ‘E’, ‘warning’: ‘W’, ‘info’: ‘I’, ‘trace’: ‘T’, ‘debug’: ‘D’}.

*dir_paths (FileDescriptorOrPath): Variadic argument containing strings

specifying the directory paths to check. If any of these file paths does not exist or is not a regular file, then a log message will be emitted and a FileNotFoundError or NotADirectoryError will raised.

_fqname(o: object) str[source]