[Majeur] Une erreur API (409, 422, 404, 500) remplace toute l'application par un écran d'erreur plein écran #148

Closed
opened 2026-10-28 10:32:23 +00:00 by asventi · 0 comments
Owner

Gravité : Majeur
Rapports QA d'origine : CHAT-13, PROFILE-10, ADMIN-14, EVENTS-19, AUTH-22, SECURITY_UX-22

Nom de channel en double, mauvais mot de passe, rôle en double, event complet… : l'erreur devrait s'afficher dans la modale ou en toast, sans perdre la saisie.

Détails des rapports

[CHAT-13] Une erreur 409/422 à la création/édition d'un channel ou d'une catégorie remplace TOUTE l'application par une page d'erreur plein écran — Gravité : Majeur
  • Où : modales "Create a category" / "Create a channel" / édition (sidebar), routes /category et /channels.
  • Étapes : 1. admin (dede) : CHANNELS > "+" (Create a category) ; nom qa_chat_ui_cat existant déjà, valider. 2. Idem pour "Create a channel" avec le nom QA_Upper_Chan (majuscules) ou qa_chat_pub (existant). 3. Idem catégorie bad<name>.
  • Attendu : message d'erreur inline dans la modale (champ Name), l'utilisateur garde son contexte.
  • Obtenu : page plein écran "Error 409 Category name already used" / "Error 422 Invalid channel name" avec boutons Go Back / Home ; la modale et l'app disparaissent. L'UI ne fait aucune validation côté client du nom de channel (minuscules, sans espaces/caractères spéciaux : sanitizeChannelSlug existe dans chat/utils/channel.util.ts mais n'est utilisé nulle part), donc taper "My Channel" ou "General" (très naturel) mène à cet écran d'erreur.
  • Preuve : screenshots screens/chat_cat_dup_ui.png, chat_ch_422_ui.png, chat_ch_409_ui.png ; console Category name already used ... at clientAction (category.route.tsx:29).
  • Cause probable : frontend/src/chat/routes/channel.route.tsx (bloc catch) et category.route.tsx : seuls les status === 400 sont retournés via data(err), les 409/422 sont throw err -> ErrorBoundary de route.
[PROFILE-10] Toute erreur serveur d'une action du profil remplace TOUTE l'application par une page d'erreur plein écran — Gravité : Majeur
  • Où : modales Paramètres (changement de nom d'utilisateur, de mot de passe, avatar…) -> /me/:action
  • Étapes : 1. Paramètres (engrenage) > Username > crayon > saisir david (nom déjà pris) > Validate. (Idem : nom composé d'espaces " " -> 400 ; mauvais mot de passe actuel dans "Change password" -> 406.)
  • Attendu : message d'erreur dans la modale (champ en erreur), la page et la sidebar restent intactes.
  • Obtenu : toute l'UI (sidebar, page) est remplacée par une carte "Error 409 / Username already used / Go Back / Home" ; l'utilisateur perd son contexte. Console : Username already used: 'david' is already used by an other user. at request (src/api/request.ts:11). Même rendu pour 400 (« One or more validation errors occurred. / The server rejected the request. ») et 406 (mauvais mdp).
  • Preuve : screens/profile_04_username_dup.png, profile_06_rename_spaces.png, profile_08_password_wrong.png
  • Cause probable : frontend/src/users/routes/me.ts:14-40 (clientAction laisse remonter l'APIError) + Profile.tsx:111-123 / useModalFetcher n'intercepte pas l'erreur ; capté par routes/dashboard.tsx:89 ErrorBoundary. Aucune validation trim() côté UI pour le nom (Profile.tsx:111-123, seulement required/minLength=1 HTML : " " passe).
[ADMIN-14] Toute erreur API d'une action admin remplace la page par un écran d'erreur plein écran (ex. rôle en double) — Gravité : Mineur
  • Où : /admin/roles (création / renommage / suppression de rôle, cases à cocher), /admin/users (suppression, mot de passe, rôle, disconnect)
  • Étapes : 1. /admin/roles -> "+ Role" -> saisir le nom d'un rôle existant -> valider
  • Attendu : message d'erreur dans la modale ou toast ("nom déjà utilisé"), la liste reste affichée.
  • Obtenu : la zone de contenu est remplacée par une carte "Error 409 – Role Name already used ... Trace: 00-..." avec boutons "Go Back"/"Home" ; la modale disparaît, la liste n'est plus visible. Même mécanisme pour toute autre erreur (une 500 de ADMIN-12 affichera ce même écran ; une 401 à corps vide, ex. ADMIN-03, donnera une erreur Unexpected end of JSON input).
  • Preuve : screens/admin_roles_02_duplicate.png ; console : Role Name already used: 'qa_admin_ui_3ncs' is already used by an other role. at createRole.
  • Cause probable : frontend/src/admin/api/roles.ts (throw new APIError(...)) + frontend/src/admin/routes/RolesAction.ts / UsersAction.ts sans try/catch : l'erreur levée par clientAction remonte à l'ErrorBoundary de route au lieu d'être renvoyée via data() (alors que useModalFetcher sait afficher un toast quand fetcher.data instanceof Error). frontend/src/api/request.ts : response.json() sur une réponse vide (401 du middleware).
[EVENTS-19] Toute erreur non-400 (ex. 409 taille < inscrits) dans le composer remplace la page par un écran d'erreur plein écran et perd la saisie — Gravité : Mineur
  • Où : modale d'édition, champ taille ; plus généralement frontend/src/events/routes/events.route.tsx:250-257 (seul le statut 400 est renvoyé à la modale, le reste est throw).
  • Étapes : event avec 2 inscrits -> éditer, taille = 1, "Save".
  • Attendu : message d'erreur dans la modale (champ Size), saisie conservée.
  • Obtenu : écran "Error 409 — Event size below its registrations" plein écran (boutons Go Back / Home), modale et saisie perdues. Même traitement pour 422 (rôle/fichier inconnu) ou 500.
  • Preuve : screenshot screens/events_edit_size_below.png.
  • Même défaut côté inscription : un user dont la page est périmée clique "Register" sur un event devenu complet -> écran plein écran "Error 409 — Event is full" (screenshot screens/events_stale_after.png) au lieu d'un toast/erreur dans la modale ; idem pour "already registered" (409), event supprimé (404) : frontend/src/events/routes/registrations.route.tsx:279-294 ne capture aucune erreur.
  • Note : la modale n'empêche pas non plus d'entrer une taille < registeredCount (SizeSlot.tsx ne reçoit registeredCount que pour l'affichage).
[AUTH-22] "Remove" d'une invitation déjà supprimée remplace toute la page par une page d'erreur 404 — Gravité : Mineur
  • Où : /admin/users (liste des invitations)
  • Étapes : 1. Ouvrir /admin/users. 2. Pendant ce temps l'invitation est supprimée ailleurs (autre admin, ou tentative d'inscription avec un code expiré qui la purge, cf. RegisterUserCommand.cs:22-27). 3. Cliquer "Remove" sur la ligne périmée.
  • Attendu : toast / simple rafraîchissement de la liste.
  • Obtenu : DELETE /api/auth/invitation/<id> -> 404 et la page entière est remplacée par la carte "Error 404 — Invitation not found" (Go Back / Home).
  • Preuve : screens/auth_27_stale_remove.png
  • Cause probable : frontend/src/invitations/routes/invitations.route.tsx:20 + frontend/src/api/request.ts:19 (l'APIError remonte à l'ErrorBoundary du dashboard).
[SECURITY_UX-22] Erreur backend 500 : message technique interne de React Router affiché à l'utilisateur — Gravité : Cosmétique
  • Où : /calendar quand GET /api/events répond 500 (simulé avec page.route)
  • Obtenu : « Something went wrong – No result returned from dataStrategy for route routes/calendar_page » (message interne du framework, pas de retry ni de texte utile). Le panneau 401 ci-dessus, lui, affiche bien un message correct.
  • Preuve : screens/security_ux_calendar_500.png

Trouvé par une campagne de tests QA automatisés (agents Claude, Playwright) sur l'environnement de dev. Les captures citées sont locales et non jointes.

**Gravité :** Majeur **Rapports QA d'origine :** CHAT-13, PROFILE-10, ADMIN-14, EVENTS-19, AUTH-22, SECURITY_UX-22 Nom de channel en double, mauvais mot de passe, rôle en double, event complet… : l'erreur devrait s'afficher dans la modale ou en toast, sans perdre la saisie. ## Détails des rapports <details><summary>[CHAT-13] Une erreur 409/422 à la création/édition d'un channel ou d'une catégorie remplace TOUTE l'application par une page d'erreur plein écran — Gravité : Majeur</summary> - Où : modales "Create a category" / "Create a channel" / édition (sidebar), routes `/category` et `/channels`. - Étapes : 1. admin (dede) : CHANNELS > "+" (Create a category) ; nom `qa_chat_ui_cat` existant déjà, valider. 2. Idem pour "Create a channel" avec le nom `QA_Upper_Chan` (majuscules) ou `qa_chat_pub` (existant). 3. Idem catégorie `bad<name>`. - Attendu : message d'erreur inline dans la modale (champ Name), l'utilisateur garde son contexte. - Obtenu : page plein écran "Error 409 Category name already used" / "Error 422 Invalid channel name" avec boutons Go Back / Home ; la modale et l'app disparaissent. L'UI ne fait aucune validation côté client du nom de channel (minuscules, sans espaces/caractères spéciaux : `sanitizeChannelSlug` existe dans `chat/utils/channel.util.ts` mais n'est utilisé nulle part), donc taper "My Channel" ou "General" (très naturel) mène à cet écran d'erreur. - Preuve : screenshots `screens/chat_cat_dup_ui.png`, `chat_ch_422_ui.png`, `chat_ch_409_ui.png` ; console `Category name already used ... at clientAction (category.route.tsx:29)`. - Cause probable : `frontend/src/chat/routes/channel.route.tsx` (bloc catch) et `category.route.tsx` : seuls les `status === 400` sont retournés via `data(err)`, les 409/422 sont `throw err` -> ErrorBoundary de route. </details> <details><summary>[PROFILE-10] Toute erreur serveur d'une action du profil remplace TOUTE l'application par une page d'erreur plein écran — Gravité : Majeur</summary> - Où : modales Paramètres (changement de nom d'utilisateur, de mot de passe, avatar…) -> `/me/:action` - Étapes : 1. Paramètres (engrenage) > Username > crayon > saisir `david` (nom déjà pris) > Validate. (Idem : nom composé d'espaces `" "` -> 400 ; mauvais mot de passe actuel dans "Change password" -> 406.) - Attendu : message d'erreur dans la modale (champ en erreur), la page et la sidebar restent intactes. - Obtenu : toute l'UI (sidebar, page) est remplacée par une carte "Error 409 / Username already used / Go Back / Home" ; l'utilisateur perd son contexte. Console : `Username already used: 'david' is already used by an other user. at request (src/api/request.ts:11)`. Même rendu pour 400 (« One or more validation errors occurred. / The server rejected the request. ») et 406 (mauvais mdp). - Preuve : `screens/profile_04_username_dup.png`, `profile_06_rename_spaces.png`, `profile_08_password_wrong.png` - Cause probable : `frontend/src/users/routes/me.ts:14-40` (`clientAction` laisse remonter l'`APIError`) + `Profile.tsx:111-123` / `useModalFetcher` n'intercepte pas l'erreur ; capté par `routes/dashboard.tsx:89` `ErrorBoundary`. Aucune validation `trim()` côté UI pour le nom (`Profile.tsx:111-123`, seulement `required`/`minLength=1` HTML : " " passe). </details> <details><summary>[ADMIN-14] Toute erreur API d'une action admin remplace la page par un écran d'erreur plein écran (ex. rôle en double) — Gravité : Mineur</summary> - Où : /admin/roles (création / renommage / suppression de rôle, cases à cocher), /admin/users (suppression, mot de passe, rôle, disconnect) - Étapes : 1. /admin/roles -> "+ Role" -> saisir le nom d'un rôle existant -> valider - Attendu : message d'erreur dans la modale ou toast ("nom déjà utilisé"), la liste reste affichée. - Obtenu : la zone de contenu est remplacée par une carte "Error 409 – Role Name already used ... Trace: 00-..." avec boutons "Go Back"/"Home" ; la modale disparaît, la liste n'est plus visible. Même mécanisme pour toute autre erreur (une 500 de ADMIN-12 affichera ce même écran ; une 401 à corps vide, ex. ADMIN-03, donnera une erreur `Unexpected end of JSON input`). - Preuve : `screens/admin_roles_02_duplicate.png` ; console : `Role Name already used: 'qa_admin_ui_3ncs' is already used by an other role. at createRole`. - Cause probable : `frontend/src/admin/api/roles.ts` (`throw new APIError(...)`) + `frontend/src/admin/routes/RolesAction.ts` / `UsersAction.ts` sans try/catch : l'erreur levée par `clientAction` remonte à l'ErrorBoundary de route au lieu d'être renvoyée via `data()` (alors que `useModalFetcher` sait afficher un toast quand `fetcher.data instanceof Error`). `frontend/src/api/request.ts` : `response.json()` sur une réponse vide (401 du middleware). </details> <details><summary>[EVENTS-19] Toute erreur non-400 (ex. 409 taille < inscrits) dans le composer remplace la page par un écran d'erreur plein écran et perd la saisie — Gravité : Mineur</summary> - Où : modale d'édition, champ taille ; plus généralement `frontend/src/events/routes/events.route.tsx:250-257` (seul le statut 400 est renvoyé à la modale, le reste est `throw`). - Étapes : event avec 2 inscrits -> éditer, taille = 1, "Save". - Attendu : message d'erreur dans la modale (champ Size), saisie conservée. - Obtenu : écran "Error 409 — Event size below its registrations" plein écran (boutons Go Back / Home), modale et saisie perdues. Même traitement pour 422 (rôle/fichier inconnu) ou 500. - Preuve : screenshot `screens/events_edit_size_below.png`. - Même défaut côté inscription : un user dont la page est périmée clique "Register" sur un event devenu complet -> écran plein écran "Error 409 — Event is full" (screenshot `screens/events_stale_after.png`) au lieu d'un toast/erreur dans la modale ; idem pour "already registered" (409), event supprimé (404) : `frontend/src/events/routes/registrations.route.tsx:279-294` ne capture aucune erreur. - Note : la modale n'empêche pas non plus d'entrer une taille < `registeredCount` (`SizeSlot.tsx` ne reçoit `registeredCount` que pour l'affichage). </details> <details><summary>[AUTH-22] "Remove" d'une invitation déjà supprimée remplace toute la page par une page d'erreur 404 — Gravité : Mineur</summary> - Où : `/admin/users` (liste des invitations) - Étapes : 1. Ouvrir /admin/users. 2. Pendant ce temps l'invitation est supprimée ailleurs (autre admin, ou tentative d'inscription avec un code expiré qui la purge, cf. `RegisterUserCommand.cs:22-27`). 3. Cliquer "Remove" sur la ligne périmée. - Attendu : toast / simple rafraîchissement de la liste. - Obtenu : `DELETE /api/auth/invitation/<id> -> 404` et la page entière est remplacée par la carte "Error 404 — Invitation not found" (Go Back / Home). - Preuve : `screens/auth_27_stale_remove.png` - Cause probable : `frontend/src/invitations/routes/invitations.route.tsx:20` + `frontend/src/api/request.ts:19` (l'APIError remonte à l'ErrorBoundary du dashboard). </details> <details><summary>[SECURITY_UX-22] Erreur backend 500 : message technique interne de React Router affiché à l'utilisateur — Gravité : Cosmétique</summary> - Où : `/calendar` quand `GET /api/events` répond 500 (simulé avec `page.route`) - Obtenu : « Something went wrong – No result returned from dataStrategy for route routes/calendar_page » (message interne du framework, pas de retry ni de texte utile). Le panneau 401 ci-dessus, lui, affiche bien un message correct. - Preuve : `screens/security_ux_calendar_500.png` </details> --- _Trouvé par une campagne de tests QA automatisés (agents Claude, Playwright) sur l'environnement de dev. Les captures citées sont locales et non jointes._
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transcendence/frontend#148
No description provided.