Skip to content

pygx.error_handling

Exception classification and contextual error capture for PyGX.

error_handling

Exception classification and contextual error capture for PyGX.

pygx.error_handling bundles the small set of error-flow primitives PyGX uses internally and exposes to callers:

  • catch_errors / CatchErrorsContext contextually suppress and aggregate matching exceptions.
  • match_error tests whether an exception matches a (type, message_pattern) selector.
  • ErrorInfo captures a structured, JSON-serializable view of an exception chain — a pg.Object so it serializes and renders cleanly.

ErrorInfo

ErrorInfo(tag: str, description: str, stacktrace: str, **kwargs)

Bases: Object, Extension

Structured, JSON-serializable view of an exception chain.

Source code in pygx/error_handling/_error_info.py
def __init__(self, tag: str, description: str, stacktrace: str, **kwargs):
    super().__init__(
        tag=tag,
        description=description,
        stacktrace=stacktrace,
        **kwargs,
    )

from_exception classmethod

from_exception(error: BaseException) -> ErrorInfo

Creates an error info from an exception.

Source code in pygx/error_handling/_error_info.py
@classmethod
def from_exception(cls, error: BaseException) -> 'ErrorInfo':
    """Creates an error info from an exception."""
    return cls(
        tag=cls._compute_tag(error),
        description=str(error),
        stacktrace=''.join(traceback.format_exception(*sys.exc_info())),
    )

CatchErrorsContext dataclass

CatchErrorsContext(error: BaseException | None = None)

Context for pg.catch_errors.

catch_errors

catch_errors(
    errors: (
        type[BaseException]
        | tuple[type[BaseException], str]
        | Sequence[type[BaseException] | tuple[type[BaseException], str]]
    ),
    error_handler: Callable[[BaseException], None] | None = None,
) -> Iterator[CatchErrorsContext]

Context manager for catching user-specified exceptions.

Examples::

with pg.utils.catch_errors( [ RuntimeErrror, (ValueError, 'Input is wrong.') ], ) as error_context: do_something()

if error_context.error: # Error branch. handle_error(error_context.error)

Parameters:

Name Type Description Default
errors type[BaseException] | tuple[type[BaseException], str] | Sequence[type[BaseException] | tuple[type[BaseException], str]]

A sequence of exception types or tuples of exception type and error messages (described in regular expression) as the desired exception types to catch. If an error is raised within the scope which does not match with the specification, it will be propagated to the outer scope.

required
error_handler Callable[[BaseException], None] | None

An optional callable object to handle the error on failure. It's usually provided if the user want to create a context manager based on pg.catch_errors with specific error handling logics.

None

Yields:

Type Description
CatchErrorsContext

A CatchErrorsContext object.

Source code in pygx/error_handling/_error_utils.py
@contextlib.contextmanager
def catch_errors(
    errors: (
        type[BaseException]
        | tuple[type[BaseException], str]
        | Sequence[type[BaseException] | tuple[type[BaseException], str]]
    ),
    error_handler: Callable[[BaseException], None] | None = None,
) -> Iterator['CatchErrorsContext']:
    """Context manager for catching user-specified exceptions.

    Examples::

      with pg.utils.catch_errors(
          [
              RuntimeErrror,
              (ValueError, 'Input is wrong.')
          ],
      ) as error_context:
        do_something()

      if error_context.error:
        # Error branch.
        handle_error(error_context.error)

    Args:
      errors: A sequence of exception types or tuples of exception type and error
        messages (described in regular expression) as the desired exception types
        to catch. If an error is raised within the scope which does not match with
        the specification, it will be propagated to the outer scope.
      error_handler: An optional callable object to handle the error on failure.
        It's usually provided if the user want to create a context manager based
        on `pg.catch_errors` with specific error handling logics.

    Yields:
      A CatchErrorsContext object.
    """
    error_mapping = _parse_error_spec(errors)
    context = CatchErrorsContext()
    try:
        yield context
    except BaseException as e:  # pylint: disable=broad-exception-caught
        if match_error(e, error_mapping):
            context.error = e
            if error_handler is not None:
                error_handler(e)
        else:
            raise

match_error

match_error(
    error: BaseException,
    errors: (
        type[BaseException]
        | tuple[type[BaseException], str]
        | Sequence[type[BaseException] | tuple[type[BaseException], str]]
        | dict[type[BaseException], list[str]]
    ),
) -> bool

Returns True if the error matches the specification, .

Parameters:

Name Type Description Default
error BaseException

The error to match.

required
errors type[BaseException] | tuple[type[BaseException], str] | Sequence[type[BaseException] | tuple[type[BaseException], str]] | dict[type[BaseException], list[str]]

A sequence of exception types or tuples of exception type and error messages (described in regular expression) as the desired exception types to match.

required

Returns:

Type Description
bool

True if the error matches the specification, False otherwise.

Source code in pygx/error_handling/_error_utils.py
def match_error(
    error: BaseException,
    errors: (
        type[BaseException]
        | tuple[type[BaseException], str]
        | Sequence[type[BaseException] | tuple[type[BaseException], str]]
        | dict[type[BaseException], list[str]]
    ),
) -> bool:
    """Returns True if the error matches the specification, .

    Args:
      error: The error to match.
      errors: A sequence of exception types or tuples of exception type and error
        messages (described in regular expression) as the desired exception types
        to match.

    Returns:
      True if the error matches the specification, False otherwise.
    """
    error_mapping = _parse_error_spec(errors)
    error_message = error.__class__.__name__ + ': ' + str(error)
    for error_type, error_regexes in error_mapping.items():
        if isinstance(error, error_type):
            if not error_regexes:
                return True
            else:
                for regex in error_regexes:
                    assert regex is not None
                    if not regex.startswith(('^', '.*')):
                        regex = '.*' + regex
                    if re.match(regex, error_message):
                        return True
    return False

options: show_root_heading: false show_root_toc_entry: false members_order: source heading_level: 2