Error Messages Guidelines
Principe fondamental
Les messages d'erreur doivent être clairs, actionnables et aider l'utilisateur à résoudre le problème.
Pattern obligatoire pour les erreurs de validation
Quand des données sont manquantes ou invalides, le message d'erreur doit suivre ce pattern :
1. [PROBLÈME] - Qu'est-ce qui ne va pas ?
2. [DÉTAILS] - Quelles données sont manquantes/invalides ?
3. [ACTION] - Comment l'utilisateur peut-il résoudre le problème ?
Exemple : Erreur de données manquantes
❌ Mauvais (vague, non actionnable)
throw new BadRequestException("Données incomplètes");
❌ Moyen (liste les problèmes mais pas les solutions)
throw new BadRequestException(
"Impossible de générer le PDF : la facture est incomplète. Manquant : contact, prestations."
);
✅ Bon (clair, détaillé, actionnable)
const missingFields = [
{
field: "contact",
label: "Client",
action: "Sélectionnez un client dans le champ 'Client' en haut de la facture",
},
{
field: "items",
label: "Prestations",
action: "Ajoutez au moins une ligne de prestation avec une description et un prix",
},
];
throw new BadRequestException(
`Impossible de générer le PDF : la facture est incomplet.\n\n` +
`Informations manquantes :\n` +
`1. **Client** : Sélectionnez un client dans le champ 'Client' en haut de la facture\n` +
`2. **Prestations** : Ajoutez au moins une ligne de prestation avec une description et un prix\n\n` +
`Complétez ces informations puis réessayez.`
);
Structure recommandée
interface MissingFieldError {
field: string; // Identifiant technique du champ
label: string; // Nom lisible par l'utilisateur
action: string; // Instructions précises pour corriger
}
function buildMissingFieldsError(
context: string, // Ex: "la facture", "le devis"
missingFields: MissingFieldError[],
): string {
const fieldsList = missingFields
.map((f, i) => `${i + 1}. **${f.label}** : ${f.action}`)
.join("\n");
return (
`Impossible de continuer : ${context} est incomplet.\n\n` +
`Informations manquantes :\n${fieldsList}\n\n` +
`Complétez ces informations puis réessayez.`
);
}
Types d'erreurs courants et leurs messages
Validation de formulaire
// Champ requis
{ field: "email", label: "Email", action: "Saisissez une adresse email valide" }
// Format invalide
{ field: "phone", label: "Téléphone", action: "Le format doit être +33 6 XX XX XX XX" }
// Valeur hors limites
{ field: "amount", label: "Montant", action: "Le montant doit être supérieur à 0€" }
Erreurs de configuration
throw new BadRequestException(
`Configuration manquante : clé API OpenAI.\n\n` +
`Pour résoudre :\n` +
`1. Allez dans Paramètres > Connexions\n` +
`2. Ajoutez votre clé API OpenAI\n` +
`3. Réessayez l'opération`
);
Erreurs de permissions
throw new ForbiddenException(
`Accès refusé : vous n'avez pas la permission de modifier cette facture.\n\n` +
`Raison : Seul le propriétaire ou un administrateur peut modifier ce document.\n\n` +
`Contactez votre administrateur si vous pensez que c'est une erreur.`
);
Règles supplémentaires
- Langue : Messages en français (langue de l'application)
- Ton : Professionnel mais accessible, jamais technique
- Markdown : Utiliser
**gras**pour les éléments importants - Numérotation : Lister les étapes si plusieurs actions sont nécessaires
- Pas de jargon : "Client" au lieu de "contact_id"
- Contexte : Toujours mentionner où l'utilisateur doit agir
Implémentation dans le frontend
Le frontend doit pouvoir afficher ces messages formatés. Les sauts de ligne (\n) doivent être respectés.
// Composant Toast ou Modal d'erreur
function ErrorMessage({ message }: { message: string }) {
return (
<div className="error-message">
{message.split('\n').map((line, i) => (
<p key={i}>{line}</p>
))}
</div>
);
}