02 mars 2025·8 min de lecture

UX des erreurs de contraintes en base : transformer les échecs en messages clairs

Apprenez comment transformer les erreurs de contrainte en base de données en messages utiles par champ en cartographiant les violations d'unicité, de clé étrangère et de NOT NULL dans votre application.

UX des erreurs de contraintes en base : transformer les échecs en messages clairs

Pourquoi les échecs de contrainte irritent autant les utilisateurs

Quand quelqu'un tape sur Enregistrer, il attend un de ces deux résultats : ça a marché, ou on lui explique rapidement ce qu'il faut corriger. Trop souvent, il obtient une bannière générique comme « Request failed » ou « Something went wrong. ». Le formulaire reste inchangé, rien n'est mis en évidence, et il doit deviner.

C'est pour combler ce fossé que l'UX des erreurs de contrainte en base est importante. La base applique des règles que l'utilisateur n'a jamais vues : « cette valeur doit être unique », « cet enregistrement doit référencer un élément existant », « ce champ ne peut pas être vide ». Si l'application cache ces règles derrière une erreur vague, les gens se sentent accusés pour un problème qu'ils ne comprennent pas.

Les erreurs génériques brisent aussi la confiance. Les gens supposent que l'application est instable, donc ils réessaient, rafraîchissent ou abandonnent la tâche. En milieu professionnel, ils envoient des captures d'écran au support qui n'aident pas, parce que la capture ne contient aucun détail utile.

Un exemple courant : quelqu'un crée un client et obtient « Save failed. ». Il réessaie avec le même email. Ça échoue encore. Il se demande alors si le système duplique des données, perd des données, ou les deux.

La base est souvent la source de vérité finale, même si vous validez côté UI. Elle voit l'état le plus récent, y compris les changements d'autres utilisateurs, jobs en arrière-plan et intégrations. Donc les échecs de contrainte vont arriver, et c'est normal.

Un bon résultat est simple : traduire une règle de la base en un message qui pointe vers un champ précis et une action suivante. Par exemple :

  • « L'email est déjà utilisé. Essayez un autre email ou connectez-vous. »
  • « Choisissez un compte valide. Le compte sélectionné n'existe plus. »
  • « Le numéro de téléphone est requis. »

Le reste de l'article explique comment faire cette traduction, pour que les échecs deviennent des récupérations rapides, que vous codez la stack à la main ou que vous utilisiez un outil comme AppMaster.

Les types de contraintes que vous rencontrerez (et ce qu'ils signifient)

La plupart des moments « request failed » proviennent d'un petit ensemble de règles en base. Si vous pouvez nommer la règle, vous pouvez en général la transformer en message clair sur le bon champ.

Voici les types de contraintes courants en langage simple :

  • Contrainte d'unicité : une valeur doit être unique. Exemples typiques : email, nom d'utilisateur, numéro de facture ou un ID externe. Lorsqu'elle échoue, l'utilisateur n'a pas « fait quelque chose de mal », il est entré en collision avec des données existantes.
  • Contrainte de clé étrangère : un enregistrement pointe vers un autre enregistrement qui doit exister (comme order.customer_id). Elle échoue quand la référence a été supprimée, n'a jamais existé, ou que l'UI a envoyé le mauvais ID.
  • Contrainte NOT NULL : une valeur requise manque au niveau de la base. Cela peut arriver même si le formulaire semble complet (par exemple l'UI n'a pas envoyé un champ, ou l'API l'a écrasé).
  • Contrainte CHECK : une valeur est en dehors d'une règle autorisée, comme « quantité doit être > 0 », « status doit être l'une de ces valeurs » ou « remise doit être entre 0 et 100 ».

La partie délicate est que le même problème réel peut apparaître différemment selon la base et les outils. Postgres peut nommer la contrainte (utile), tandis qu'un ORM peut l'encapsuler dans une exception générique (peu utile). Même une contrainte d'unicité peut se manifester par « duplicate key », « unique violation » ou un code d'erreur spécifique au fournisseur.

Un exemple pratique : quelqu'un modifie un client dans un panneau d'administration, clique sur Enregistrer et obtient une erreur. Si l'API peut indiquer à l'UI qu'il s'agissait d'une contrainte d'unicité sur email, vous pouvez afficher « Cet email est déjà utilisé » sous le champ Email au lieu d'un toast vague.

Traitez chaque type de contrainte comme un indice sur ce que la personne peut faire ensuite : choisir une autre valeur, sélectionner un enregistrement lié existant, ou remplir le champ requis manquant.

Ce qu'un bon message par champ doit accomplir

Un échec de contrainte en base est un événement technique, mais l'expérience doit ressembler à un guidage normal. Une bonne UX transforme « quelque chose a planté » en « voici ce qu'il faut corriger », sans faire deviner l'utilisateur.

Utilisez un langage simple. Remplacez les mots de la base comme « unique index » ou « foreign key » par ce qu'un humain dirait. « Cet email est déjà utilisé » est bien plus utile que « duplicate key value violates unique constraint ».

Placez le message là où l'action se déroule. Si l'erreur appartient clairement à une saisie, attachez-la à ce champ pour que l'utilisateur puisse le corriger immédiatement. Si c'est au niveau de l'action entière (par exemple « vous ne pouvez pas supprimer ceci car il est utilisé ailleurs »), affichez-le au niveau du formulaire avec une prochaine étape claire.

Le spécifique l'emporte sur le poli. Un message utile répond à deux questions : quoi changer et pourquoi cela a été rejeté. « Choisissez un autre nom d'utilisateur » est mieux que « Nom d'utilisateur invalide ». « Sélectionnez un client avant d'enregistrer » est mieux que « Données manquantes ».

Faites attention aux détails sensibles. Parfois, le message le plus « utile » divulgue des informations. Sur un écran de connexion ou de réinitialisation de mot de passe, dire « Aucun compte n'existe pour cet email » peut aider des attaquants. Dans ces cas, utilisez un message plus sûr comme « Si un compte correspond à cet email, vous recevrez un message bientôt. »

Prévoyez aussi plusieurs problèmes à la fois. Une seule sauvegarde peut échouer sur plusieurs contraintes. Votre UI doit pouvoir afficher plusieurs messages de champ ensemble, sans surcharger l'écran.

Un message solide par champ utilise des mots simples, pointe vers le bon champ (ou est clairement de niveau formulaire), indique ce qu'il faut changer, évite de révéler des faits privés sur des comptes ou enregistrements, et supporte plusieurs erreurs dans la même réponse.

Concevoir un contrat d'erreur entre l'API et l'UI

Une bonne UX commence par un accord : quand quelque chose échoue, l'API dit à l'UI exactement ce qui s'est passé, et l'UI l'affiche de la même manière à chaque fois. Sans ce contrat, vous retombez dans un toast générique qui n'aide personne.

Une forme d'erreur pratique est petite mais précise. Elle doit contenir un code d'erreur stable, le champ (lorsqu'il correspond à une saisie unique), un message humain, et des détails optionnels pour le logging.

{
  "error": {
    "code": "UNIQUE_VIOLATION",
    "field": "email",
    "message": "That email is already in use.",
    "details": {
      "constraint": "users_email_key",
      "table": "users"
    }
  }
}

L'essentiel est la stabilité. N'exposez pas le texte brut de la base aux utilisateurs, et n'obligez pas l'UI à parser les chaînes d'erreur Postgres. Les codes doivent être cohérents entre plateformes (web, iOS, Android) et entre endpoints.

Décidez à l'avance comment vous représentez les erreurs de champ vs les erreurs de formulaire. Une erreur de champ signifie qu'une saisie est bloquée (définissez field, affichez le message sous l'entrée). Une erreur de niveau formulaire signifie que l'action ne peut pas être complétée même si les champs semblent valides (laissez field vide, affichez le message près du bouton Enregistrer). Si plusieurs champs peuvent échouer à la fois, renvoyez un tableau d'erreurs, chacune avec son propre field et code.

Pour que le rendu reste cohérent, rendez vos règles UI ennuyeuses et prévisibles : affichez la première erreur en haut comme court résumé et en ligne près du champ, gardez les messages courts et actionnables, réutilisez la même formulation à travers les flux (inscription, édition de profil, écrans admin), et enregistrez les details tout en montrant seulement message à l'utilisateur.

Si vous construisez avec AppMaster, traitez ce contrat comme toute autre sortie d'API. Votre backend peut renvoyer la forme structurée, et vos apps web (Vue3) et mobiles générées peuvent la rendre avec un pattern partagé, afin que chaque échec de contrainte ressemble à un guidage, pas à un plantage.

Étape par étape : traduire les erreurs DB en messages par champ

Traduire proprement les erreurs DB
Transformez les échecs d'unicité, de clé étrangère et de champs requis en messages que les utilisateurs peuvent corriger rapidement.
Essayez maintenant

Une bonne UX des erreurs de contrainte commence par considérer la base comme le juge final, pas comme la première ligne de feedback. Les utilisateurs ne doivent jamais voir du texte SQL brut, des traces de pile ou un vague « request failed ». Ils doivent voir quel champ nécessite une correction et quoi faire ensuite.

Un flux pratique qui marche dans la plupart des stacks :

  1. Décidez où l'erreur est interceptée. Choisissez un seul endroit où les erreurs de base deviennent des réponses d'API (souvent la couche repository/DAO ou un handler global d'erreurs). Cela évite le chaos « parfois inline, parfois toast ».
  2. Classifiez l'échec. Lorsqu'une écriture échoue, détectez la classe : contrainte d'unicité, clé étrangère, NOT NULL ou contrainte CHECK. Utilisez les codes d'erreur du driver quand c'est possible. Évitez de parser le texte humain sauf si vous n'avez pas le choix.
  3. Mappez les noms de contrainte aux champs du formulaire. Les contraintes sont d'excellents identifiants, mais les UI ont besoin de clés de champ. Conservez un lookup simple comme users_email_key -> email ou orders_customer_id_fkey -> customerId. Placez-le près du code qui possède le schéma.
  4. Générez un message sûr. Construisez un texte court et convivial par classe, pas à partir du message brut de la base. Unique -> « Cette valeur est déjà utilisée. » FK -> « Choisissez un client existant. » NOT NULL -> « Ce champ est requis. » Check -> « Valeur hors plage autorisée. »
  5. Retournez des erreurs structurées et affichez-les inline. Envoyez une payload cohérente (par exemple : [{ field, code, message }]). Dans l'UI, attachez les messages aux champs, scrollez et focussez le premier champ en échec, et gardez toute bannière globale comme résumé seulement.

Si vous construisez avec AppMaster, appliquez la même idée : capturez l'erreur de la base en un endroit backend, traduisez-la dans un format d'erreur par champ prévisible, puis affichez-la à côté de l'entrée dans votre UI web ou mobile. Cela maintient l'expérience cohérente même si votre modèle de données évolue.

Un exemple réaliste : trois sauvegardes échouées, trois résultats utiles

Ces échecs sont souvent compressés en un seul toast générique. Chacun mérite un message différent, même s'ils proviennent tous de la base.

1) Inscription : email déjà utilisé (contrainte d'unicité)

Échec brut (ce que vous verrez peut-être dans les logs) : duplicate key value violates unique constraint "users_email_key"

Ce que l'utilisateur devrait voir : « Cet email est déjà enregistré. Essayez de vous connecter, ou utilisez un autre email. »

Placez le message à côté du champ Email et conservez le formulaire rempli. Si possible, proposez une action secondaire comme « Se connecter », pour qu'il n'ait pas à deviner ce qu'il s'est passé.

2) Création de commande : client manquant (clé étrangère)

Échec brut : insert or update on table "orders" violates foreign key constraint "orders_customer_id_fkey"

Ce que l'utilisateur devrait voir : « Choisissez un client pour passer cette commande. »

Cela ne ressemble pas à une « erreur » pour l'utilisateur. Ça ressemble à un contexte manquant. Mettez en évidence le sélecteur Client, conservez les lignes de commande qu'il a déjà ajoutées, et si le client a été supprimé dans un autre onglet, dites-le franchement : « Ce client n'existe plus. Choisissez-en un autre. »

3) Mise à jour de profil : champ requis manquant (NOT NULL)

Échec brut : null value in column "last_name" violates not-null constraint

Ce que l'utilisateur devrait voir : « Le nom de famille est requis. »

Voilà à quoi ressemble un bon traitement des contraintes : un feedback normal de formulaire, pas une défaillance système.

Pour aider le support sans divulguer des détails techniques aux utilisateurs, conservez l'erreur complète dans les logs (ou un panneau d'erreur interne) : incluez un request ID et user/session ID, le nom de contrainte (si disponible) et table/champ, la payload de l'API (masquez les champs sensibles), le timestamp et l'endpoint/action, ainsi que le message affiché à l'utilisateur.

Erreurs de clé étrangère : aider l'utilisateur à récupérer

Stop aux bannières d'erreur génériques
Centralisez le traitement des erreurs côté backend pour que chaque écran affiche les mêmes messages utiles.
Se lancer

Les échecs de clé étrangère signifient généralement que la personne a choisi quelque chose qui n'existe plus, n'est plus autorisé, ou ne correspond plus aux règles actuelles. L'objectif n'est pas seulement d'expliquer l'échec, mais de fournir une prochaine action claire.

La plupart du temps, une erreur de clé étrangère se mappe à un seul champ : le sélecteur qui référence un autre enregistrement (Client, Projet, Assigné). Le message doit nommer la chose que l'utilisateur reconnaît, pas le concept de la base. Évitez les IDs internes ou les noms de table. « Client n'existe plus » est utile. « FK_orders_customer_id violated (customer_id=42) » ne l'est pas.

Un bon pattern de récupération traite l'erreur comme une sélection périmée. Incitez l'utilisateur à re-sélectionner depuis la liste la plus récente (rafraîchir le dropdown ou ouvrir le picker de recherche). Si l'enregistrement a été supprimé ou archivé, dites-le clairement et orientez vers une alternative active. Si l'utilisateur n'a plus les droits, indiquez « Vous n'avez plus la permission d'utiliser cet élément », et proposez d'en choisir un autre ou de contacter un administrateur. Si la création d'un enregistrement lié est une étape normale suivante, offrez « Créer un nouveau client » plutôt que d'obliger un réessai.

Les enregistrements supprimés et archivés sont un piège courant. Si votre UI peut afficher les items inactifs pour le contexte, étiquetez-les clairement (Archivé) et empêchez la sélection. Cela évite l'échec, tout en gérant le cas où un autre utilisateur a modifié les données.

Parfois une erreur de clé étrangère devrait être de niveau formulaire, pas de champ. Faites-le quand vous ne pouvez pas dire de manière fiable quelle référence a causé l'erreur, quand plusieurs références sont invalides, ou quand le vrai problème concerne les permissions sur toute l'action.

NOT NULL et validation : prévenir l'erreur, tout en la gérant

Créer une réponse d'API plus sûre
Retournez des codes d'erreur stables depuis vos APIs et gardez le texte brut de la base hors de l'UI.
Construire le backend

Les échecs NOT NULL sont les plus faciles à prévenir et les plus agaçants quand ils passent à travers. Si quelqu'un voit « request failed » après avoir laissé un champ requis vide, la base fait le travail de l'UI. Une bonne UX signifie que l'UI bloque les cas évidents, et que l'API renvoie malgré tout des erreurs claires par champ quand quelque chose est manqué.

Commencez par des vérifications préalables dans le formulaire. Indiquez les champs requis près de l'entrée, pas dans une bannière générique. Un court indice comme « Requis pour les reçus » est plus utile qu'un simple astérisque rouge. Si un champ est requis de façon conditionnelle (par exemple « Raison sociale » seulement quand « Type de compte = Entreprise »), rendez cette règle visible au moment où elle devient pertinente.

La validation UI ne suffit pas. Les utilisateurs peuvent la contourner avec des versions anciennes de l'app, des réseaux instables, des réessais automatiques, des imports en masse ou de l'automatisation. Reproduisez les mêmes règles côté API pour ne pas gaspiller un aller-retour pour finalement échouer en base.

Conservez une formulation cohérente à travers l'application pour que les gens comprennent ce que signifie chaque message. Pour les valeurs manquantes, utilisez « Requis. » Pour les limites de longueur, utilisez « Trop long (max 50 caractères). » Pour les vérifications de format, utilisez « Format invalide (utilisez [email protected]). » Pour les problèmes de type, utilisez « Doit être un nombre. »

Les mises à jour partielles compliquent NOT NULL. Un PATCH qui omet un champ requis ne devrait pas échouer si la valeur existante est déjà présente, mais il doit échouer si le client le définit explicitement à null ou à une valeur vide. Décidez cette règle une fois, documentez-la et appliquez-la de façon cohérente.

Une approche pratique est de valider sur trois couches : règles côté client, validation de la requête API, et un filet de sécurité final qui attrape une erreur NOT NULL en base et la mappe au bon champ.

Erreurs courantes qui ramènent à « request failed »

La manière la plus rapide de ruiner la gestion des contraintes est de faire tout le travail côté base, puis de cacher le résultat derrière un toast générique. Les utilisateurs se fichent qu'une contrainte ait été déclenchée. Ils veulent savoir quoi corriger, où, et si leurs données sont en sécurité.

Une erreur commune est d'afficher le texte brut de la base. Des messages comme duplicate key value violates unique constraint ressemblent à un crash, même quand l'app peut récupérer. Ils créent aussi des tickets support car les utilisateurs copient du texte inquiétant au lieu de corriger un champ.

Un autre piège est de se baser sur le matching de chaînes. Ça marche jusqu'à ce que vous changiez de driver, que vous mettiez Postgres à jour, ou que vous renommiez une contrainte. Alors votre mapping « email déjà utilisé » cesse silencieusement de fonctionner, et vous retombez dans « request failed ». Préférez des codes d'erreur stables et incluez le nom de champ que votre UI comprend.

Les changements de schéma cassent le mapping de champs plus souvent qu'on ne le croit. Un renommage de email en primary_email peut transformer un message clair en données sans lieu d'affichage. Faites du mapping une partie du même ensemble de modifications que la migration, et échouez bruyamment dans les tests si une clé de champ est inconnue.

Un grand tue-l'UX est de transformer chaque échec de contrainte en HTTP 500 sans corps. Cela dit à l'UI « c'est la faute du serveur », donc elle ne peut pas afficher d'indices par champ. La plupart des échecs de contrainte sont récupérables par l'utilisateur, donc retournez une réponse de style validation avec des détails.

Quelques patterns à surveiller :

  • Messages d'email unique qui confirment l'existence d'un compte (utilisez une formulation neutre dans les flux d'inscription)
  • Gérer « une erreur à la fois » et masquer le deuxième champ cassé
  • Formulaires multi-étapes qui perdent les erreurs après un clic précédent/suivant
  • Réessais qui soumettent des valeurs périmées et écrasent le message correct du champ
  • Logging qui perd le nom de contrainte ou le code d'erreur, rendant les bugs difficiles à tracer

Par exemple, si un formulaire d'inscription dit « Email already exists », vous pouvez divulguer l'existence d'un compte. Un message plus sûr est « Vérifiez votre email ou essayez de vous connecter », tout en attachant l'erreur au champ email.

Checklist rapide avant la mise en production

Livrer la même UX en production
Déployez sur AppMaster Cloud ou votre cloud favori quand votre flux de validation est prêt.
Commencer la construction

Avant de livrer, vérifiez les petits détails qui décident si un échec de contrainte ressemble à un coup de pouce utile ou à une impasse.

Réponse API : l'UI peut-elle vraiment agir dessus ?

Assurez-vous que chaque échec de type validation renvoie suffisamment de structure pour pointer vers une saisie spécifique. Pour chaque erreur, retournez un field, un code stable, et un message lisible. Couvrez les cas fréquents de la base (unique, clé étrangère, NOT NULL, check). Gardez les détails techniques pour les logs, pas pour les utilisateurs.

Comportement UI : aide-t-il la personne à récupérer ?

Même un message parfait fait mauvaise impression si le formulaire se bat contre l'utilisateur. Focalisez le premier champ en échec et faites-le défiler en vue si nécessaire. Conservez ce que l'utilisateur a déjà tapé (surtout après des erreurs multi-champs). Affichez d'abord les erreurs au niveau des champs, avec un court résumé uniquement quand c'est utile.

Logging et tests : détectez-vous les régressions ?

La gestion des contraintes casse souvent silencieusement quand les schémas changent, donc traitez-la comme une fonctionnalité maintenue. Logger l'erreur DB en interne (nom de contrainte, table, opération, request ID), mais ne l'affichez jamais directement. Ajoutez des tests pour au moins un exemple par type de contrainte, et vérifiez que votre mapping reste stable même si le libellé exact de la base change.

Étapes suivantes : rendre cela cohérent dans toute l'application

La plupart des équipes corrigent les erreurs de contrainte écran par écran. C'est utile, mais les utilisateurs remarquent les incohérences : un formulaire affiche un message clair, un autre affiche encore « request failed ». La cohérence transforme cela d'un rustine en un vrai pattern.

Commencez là où ça fait mal. Analysez une semaine de logs ou de tickets support et identifiez les quelques contraintes qui reviennent le plus. Ces « coupables fréquents » doivent être les premiers à obtenir des messages conviviaux et par champ.

Considérez la traduction des erreurs comme une petite feature produit. Gardez une table de mapping partagée que toute l'application utilise : nom de contrainte (ou code) -> nom de champ -> message -> indice de récupération. Gardez les messages simples et les indices actionnables.

Un plan de déploiement léger qui tient dans un cycle produit chargé :

  • Identifiez les 5 contraintes que les utilisateurs rencontrent le plus et rédigez le message exact à afficher.
  • Ajoutez une table de mapping et utilisez-la sur chaque endpoint qui sauvegarde des données.
  • Standardisez la façon dont les formulaires rendent les erreurs (même emplacement, même ton, même comportement de focus).
  • Faites relire les messages par un collègue non technique et demandez : « Que feriez-vous ensuite ? »
  • Ajoutez un test par formulaire qui vérifie que le bon champ est surligné et que le message est lisible.

Si vous voulez construire ce comportement cohérent sans coder chaque écran, AppMaster (appmaster.io) prend en charge les APIs backend ainsi que des apps web et mobiles générées. Cela facilite la réutilisation d'un format d'erreur structuré entre clients, pour que le feedback par champ reste cohérent quand votre modèle de données évolue.

Rédigez aussi une courte note de « style de message d'erreur » pour votre équipe. Restez simple : quelles expressions éviter (termes de base de données) et ce que chaque message doit contenir (ce qui s'est passé, quoi faire ensuite).

FAQ

Pourquoi les erreurs de contrainte en base sont-elles si frustrantes pour les utilisateurs ?

Considérez-le comme un feedback normal de formulaire, pas comme un plantage système. Affichez un message court près du champ exact qui nécessite une modification, conservez les saisies de l'utilisateur et expliquez l'étape suivante en langage simple.

Quelle est la différence entre une erreur au niveau du champ et un message générique « request failed » ?

Une erreur au niveau d'un champ pointe vers une saisie précise et indique ce qu'il faut corriger, par exemple « L'email est déjà utilisé. ». Un message générique force l'utilisateur à deviner, à réessayer ou à contacter le support parce qu'il ne sait pas quoi changer.

Comment détecter de manière fiable quelle contrainte a échoué ?

Utilisez les codes d'erreur stables fournis par le driver de la base quand c'est possible, puis mappez-les en types compréhensibles (unicité, clé étrangère, requis, plage). Évitez d'analyser le texte brut de la base car il varie selon les drivers et versions.

Comment mapper un nom de contrainte au bon champ du formulaire ?

Conservez une table de correspondance simple du nom de contrainte vers la clé de champ UI dans le backend, près de l'endroit qui possède le schéma. Par exemple, mappez une contrainte unique sur email vers le champ email pour que l'UI puisse surligner la bonne saisie sans deviner.

Que dire pour une erreur de contrainte d'unicité (par exemple email en double) ?

Par défaut : « Cette valeur est déjà utilisée » plus une action claire comme « Essayez une autre » ou « Se connecter », selon le contexte. Dans les flux d'inscription ou de réinitialisation, utilisez un libellé neutre pour ne pas confirmer l'existence d'un compte.

Comment gérer les erreurs de clé étrangère sans embrouiller les gens ?

Expliquez-le comme une sélection périmée ou invalide que l'utilisateur reconnaît, par exemple « Ce client n'existe plus. Choisissez un autre. ». Si l'utilisateur ne peut pas récupérer sans créer un enregistrement lié, proposez ce chemin dans l'UI plutôt que de forcer des réessais.

Si mon UI valide les champs requis, pourquoi des erreurs NOT NULL surviennent-elles encore ?

Marquez les champs requis dans l'UI et validez avant l'envoi, mais traitez quand même l'échec en base comme filet de sécurité. Quand cela arrive, affichez simplement « Requis » sur le champ et conservez le reste du formulaire intact.

Comment gérer plusieurs erreurs de contrainte lors d'une seule sauvegarde ?

Retournez un tableau d'erreurs, chacune avec une clé de champ, un code stable et un message court, pour que l'UI puisse les afficher simultanément. Côté client, focalisez le premier champ en échec tout en gardant visibles les autres messages afin d'éviter le cycle « une erreur à la fois ».

Que doit contenir une réponse d'erreur d'API pour que l'UI puisse l'afficher correctement ?

Utilisez une payload cohérente qui sépare ce que voit l'utilisateur des informations de log, par exemple un message utilisateur et des détails internes (nom de contrainte, request ID). N'exposez jamais de messages SQL bruts à l'utilisateur et ne faites pas parser les chaînes de la base côté UI.

Comment garder la gestion des erreurs de contrainte cohérente sur web et mobile ?

Centralisez la traduction côté backend, renvoyez une forme d'erreur prévisible et affichez-la de la même manière dans chaque formulaire. Avec AppMaster, vous pouvez appliquer ce contrat d'erreur structuré aux APIs backend générées et aux UI web/mobile, ce qui aide à garder les messages cohérents lorsque votre modèle de données évolue.

Facile à démarrer
Créer quelque chose d'incroyable

Expérimentez avec AppMaster avec un plan gratuit.
Lorsque vous serez prêt, vous pourrez choisir l'abonnement approprié.

Démarrer