"""Base exception class for every application built on mgf.common.

See ``docs/standards/ERROR_HANDLING.md`` rule EH-01:

> Every exception raised by application code MUST be a subclass of
> the project's base error class. Never raise a bare ``Exception`` or
> a third-party exception across an internal API.

Consumer projects typically alias :class:`AppError` under a
project-specific name to make ``except`` blocks read naturally::

    # In vmanager/exceptions.py:
    from mgf.common.exceptions import AppError
    vm-vmanager-appError = AppError                    # alias preserves
                                                # ``except vm-vmanager-appError:``
                                                # call sites.

Why ``AppError`` is in its own file separate from
``_well_known.py``: it has no dependencies on the categories, and
keeping it isolated lets ``_well_known`` import it without any risk
of circular imports.
"""

from __future__ import annotations


class AppError(Exception):
    """Base class for every exception raised by application code.

    Subclasses MUST set machine-readable attributes in ``__init__``
    BEFORE calling ``super().__init__(message)``, so callers can read
    ``.attr`` without parsing the message string. Pattern (rule EH-08):

    .. code-block:: python

        class CommandError(OperationError):
            def __init__(self, argv: list[str], returncode: int) -> None:
                self.argv = list(argv)              # set fields first
                self.returncode = returncode
                super().__init__(                   # then build message
                    f"command {argv[0]} exited {returncode}"
                )

    The string representation is for humans (``str(exc)``); the
    fields are for the program (``exc.argv``, ``exc.returncode``).
    """


__all__ = ["AppError"]
