Files
2026-09-08 11:28:02 +02:00

108 lines
3.4 KiB
Python

"""Hiérarchie d'erreurs transversale du projet pronote-sync."""
from __future__ import annotations
from enum import StrEnum
class PronoteSyncError(Exception):
"""Erreur de base pour toutes les exceptions du projet pronote-sync.
Toutes les exceptions métier héritent de cette classe pour permettre
une interception unifiée des erreurs applicatives.
"""
def __init__(self, message: str) -> None:
"""Initialise l'erreur avec un message descriptif.
:param message: Message décrivant la cause de l'erreur.
"""
super().__init__(message)
self.message = message
class ErrorSeverity(StrEnum):
"""Niveau de gravité d'une erreur produite par le pipeline."""
WARNING = "warning"
CRITICAL = "critical"
class PipelineError(PronoteSyncError):
"""Erreur structurée produite par une étape du pipeline.
:ivar severity: Niveau de gravité de l'erreur.
:ivar step: Étape ayant produit l'erreur, si elle est connue.
:ivar recoverable: Indique si le pipeline peut poursuivre son exécution.
"""
def __init__(
self,
message: str,
*,
severity: ErrorSeverity = ErrorSeverity.WARNING,
step: str | None = None,
recoverable: bool = True,
) -> None:
"""Initialise une erreur de pipeline.
:param message: Message descriptif expurgé.
:param severity: Niveau de gravité associé.
:param step: Étape ayant produit l'erreur.
:param recoverable: ``True`` si le pipeline peut continuer.
"""
super().__init__(message)
self.severity = severity
self.step = step
self.recoverable = recoverable
class PipelineCriticalError(PipelineError):
"""Erreur critique du pipeline, levée quand aucune récupération n'est possible.
Par exemple : échec simultané des sources iCal et pronotepy,
rendant impossible toute synchronisation.
"""
def __init__(self, message: str, step: str | None = None) -> None:
"""Initialise l'erreur critique avec un message descriptif.
:param message: Message décrivant la cause de l'erreur critique.
:param step: Étape ayant produit l'erreur critique.
"""
super().__init__(
message,
severity=ErrorSeverity.CRITICAL,
step=step,
recoverable=False,
)
class PipelineWarning(PipelineError):
"""Avertissement non bloquant pour une erreur récupérable du pipeline.
Contrairement à :class:`PipelineCriticalError`, cet avertissement signale
un problème récupérable : le pipeline peut poursuivre son exécution en
mode dégradé.
Il hérite volontairement de :class:`PronoteSyncError` (et non de la classe
native :class:`Warning`) afin de rester dans la hiérarchie canonique des
erreurs du projet.
:ivar recoverable: Indique que l'erreur est récupérable (toujours ``True``).
:ivar step: Étape du pipeline ayant produit l'avertissement.
"""
def __init__(self, message: str, step: str | None = None) -> None:
"""Initialise l'avertissement avec un message descriptif.
:param message: Message décrivant la cause de l'avertissement.
:param step: Étape du pipeline ayant produit l'avertissement.
"""
super().__init__(
message,
severity=ErrorSeverity.WARNING,
step=step,
recoverable=True,
)