Documentation Index
Fetch the complete documentation index at: https://docs.chataigne.ai/llms.txt
Use this file to discover all available pages before exploring further.
La gestion des erreurs dans le Domain Layer suit une approche simple et directe. Nous utilisons une seule classe d’erreur pour toutes les erreurs du domaine, ce qui facilite la traçabilité et la maintenance.
Structure
Erreur de Base
class DomainError extends Error {
constructor(message: string) {
super(message);
this.name = "DomainError";
}
}
Utilisation
Dans les Entités
class Order {
constructor(items: OrderItem[]) {
if (!items || items.length === 0) {
throw new DomainError("Une commande doit contenir au moins un article");
}
// ...
}
}
class Customer {
constructor(email: string) {
if (!email || !this.isValidEmail(email)) {
throw new DomainError("Email invalide");
}
// ...
}
}
Bonnes Pratiques
- Messages d’Erreur
- Messages clairs et descriptifs
- En français
- Explication du problème
- Pas de détails techniques
- Emplacement
- Dans les constructeurs
- Dans les méthodes de validation
- Dans les méthodes de changement d’état
- Dans les méthodes de calcul
- Validation
- Valider les données d’entrée
- Vérifier les invariants
- Protéger l’intégrité des données
- Assurer la cohérence des états
Propagation
Les erreurs du domaine sont propagées vers le haut :
- Domain Layer → Application Layer
- Application Layer → Presentation Layer
- Presentation Layer → Client
Chaque layer peut :
- Logger l’erreur
- Transformer l’erreur si nécessaire
- Ajouter du contexte
- Décider de la gestion finale
Intégration avec le Logging
class OrderService {
constructor(private readonly logger: AxiomLogger) {}
async createOrder(order: Order) {
try {
await this.logger.info(
"Tentative de création de commande",
"OrderService"
);
if (!order.items.length) {
await this.logger.error("Commande sans articles", "OrderService");
throw new DomainError("Une commande doit contenir au moins un article");
}
await this.logger.info("Commande créée avec succès", "OrderService");
} catch (error) {
await this.logger.error(
`Erreur lors de la création de la commande: ${error.message}`,
error.stack,
"OrderService"
);
throw error;
}
}
}
Exemples d’Utilisation
Validation de Données
class Price {
constructor(amount: number, currency: string) {
if (amount < 0) {
throw new DomainError("Le prix ne peut pas être négatif");
}
if (!["CHF", "EUR"].includes(currency)) {
throw new DomainError("Devise non supportée");
}
// ...
}
}
Protection d’Invariants
class Order {
public cancel() {
if (this.status !== "new" && this.status !== "accepted") {
throw new DomainError("Impossible d'annuler une commande dans cet état");
}
// ...
}
}
Cohérence des États
class Customer {
public addOrder(order: Order) {
if (order.customerId !== this.id) {
throw new DomainError("La commande n'appartient pas à ce client");
}
// ...
}
}
Avantages de cette Approche
- Simplicité
- Une seule classe d’erreur
- Messages clairs
- Facile à maintenir
- Traçabilité
- Stack trace claire
- Origine de l’erreur évidente
- Contexte préservé
- Maintenance
- Code simple
- Facile à comprendre
- Facile à modifier
- Performance
- Pas de surcharge
- Pas de complexité inutile
- Stack trace optimisée