"""Hiérarchie d'exceptions de l'audit-pqc-readiness.
Chaque classe correspond à un cas d'échec RÉEL du pipeline (cible absente,
permissions, catalogue de règles malformé, écriture du rapport impossible).
Aucune exception générique ne doit être levée directement : toujours la
sous-classe la plus précise, pour permettre un traitement exhaustif (une
branche par cas) côté main(), jamais un `except` générique silencieux.
"""
class ErreurAudit(Exception):
"""Base commune — ne jamais lever directement, toujours une sous-classe."""
class ErreurCibleIntrouvable(ErreurAudit):
"""Le dossier ou fichier cible n'existe pas (vérifié AVANT tout scan)."""
class ErreurCibleNonAccessible(ErreurAudit):
"""Permission refusée sur la cible ou un de ses sous-éléments (PermissionError)."""
class ErreurReglesInvalides(ErreurAudit):
"""Le catalogue regles_pqc.json est illisible, malformé, ou contient
un motif regex invalide — jamais supposé correct sans vérification."""
def __init__(self, detail: str):
self.detail = detail
super().__init__(f"Catalogue de règles invalide : {detail}")
class ErreurEcritureRapport(ErreurAudit):
"""Le rapport de sortie n'a pas pu être écrit (--out) : dossier parent
non créable, disque plein, permissions."""
class ErreurInterne(ErreurAudit):
"""Dernier recours NOMMÉ pour tout cas non prévu ci-dessus — jamais un
`except Exception: pass` silencieux. Toujours loggé avec la cause
d'origine (`raise ... from e`), jamais avalé."""
def __init__(self, cause: Exception):
self.cause = cause
super().__init__(f"Erreur interne non catégorisée : {type(cause).__name__}: {cause}")