"""C2 VprStrategy error taxonomy (AZ-336).

Every ``VprStrategy`` method raises only members of :class:`VprError`.
Lower-level exceptions from the backbone runtime (TRT deserialize,
CUDA OOM, ONNX runtime IO mismatch, FAISS index torn mmap) MUST be
caught and rewrapped by the concrete strategy — the contract closes
the error envelope so consumers can ``except VprError`` once and
handle the family.

A separate composition-time error
(:class:`gps_denied_onboard.runtime_root.errors.StrategyNotAvailableError`)
lives outside this family — it is raised by the factory, not by a
``VprStrategy`` method.

Note: C6 ``c6_tile_cache.errors`` also defines an
``IndexUnavailableError`` for the underlying ``DescriptorIndex``
search path. The two classes are intentionally distinct (same name,
different namespaces): the C2 family is the closed envelope a C5/C2.5
consumer sees; the C6 family is the storage-layer error a concrete
strategy is responsible for rewrapping.
"""

from __future__ import annotations

__all__ = [
    "IndexUnavailableError",
    "VprBackboneError",
    "VprError",
    "VprPreprocessError",
]


class VprError(Exception):
    """Base class for the C2 VPR error family.

    Caught at the runtime root; downstream effect per AC-1.4:
    C5 falls back to VIO-only with provenance ``visual_propagated``.
    """


class VprBackboneError(VprError):
    """Backbone forward pass failed.

    CUDA OOM, TRT engine deserialize mismatch, ONNX runtime IO
    shape mismatch. Logged at ERROR; one FDR record per occurrence.
    """


class VprPreprocessError(VprError):
    """Input frame violates the backbone's preprocessing contract.

    Wrong colour channels, calibration mismatch. Logged at ERROR;
    one FDR record per occurrence. The concrete preprocessor
    (each strategy owns its own per description.md § 6) raises this
    and the strategy lets it propagate unchanged.
    """


class IndexUnavailableError(VprError):
    """FAISS index handle invalid for the strategy's retrieve path.

    Post-F8 reboot before warm-up, out-of-band file replacement
    caught by the underlying mmap defence, dim mismatch caught at
    search time. The strategy MUST raise this rather than return
    stale candidates (C2-ST-01).
    """
