mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
capitalisation
This commit is contained in:
@@ -278,3 +278,107 @@ async updateThread(forumSlug, threadId, body) {
|
||||
- **Règle** : toute méthode store qui appelle le service réseau doit soit (1) relancer l'erreur enrichie avec `throw err`, soit (2) la stocker dans le state (`set({ error: err.message })`). Jamais les deux à la fois sans rethrow si l'écran doit réagir au catch.
|
||||
|
||||
- Contexte technique : React Native / Zustand — app-alexandrie 24-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-catch-objet-throw-vs-error"></a>
|
||||
## Catch Zustand : objet structuré throwé vs instance `Error`
|
||||
|
||||
### Risques
|
||||
|
||||
- Quand `apiRequest` propage une erreur HTTP en throwant le JSON brut `{ error: { code, message } }`, un catch limité à `err instanceof Error` laisse le message inaccessible → fallback générique ou message vide affiché
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Toast "Erreur de connexion au serveur" affiché même quand le serveur retourne un message explicite
|
||||
- `err.message` undefined alors que `(err as ApiError).error.message` contient la cause réelle
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
catch (err: unknown) {
|
||||
let message = 'Erreur de connexion au serveur.';
|
||||
if (err instanceof Error) {
|
||||
message = err.message;
|
||||
} else if (
|
||||
typeof err === 'object' && err !== null &&
|
||||
'error' in err &&
|
||||
typeof (err as { error: { message?: string } }).error?.message === 'string'
|
||||
) {
|
||||
message = (err as { error: { message: string } }).error.message;
|
||||
}
|
||||
set({ error: message, isLoading: false });
|
||||
}
|
||||
```
|
||||
|
||||
- Règle : tout store qui appelle `apiRequest` directement doit inspecter les deux cas — `Error` natif et objet structuré `{ error: { message } }`
|
||||
- Contexte technique : React Native / Zustand — app-alexandrie review 5.2, 27-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-flag-global-actions-paralleles"></a>
|
||||
## Flag booléen global pour des actions par entité — préférer `Set<string>`
|
||||
|
||||
### Risques
|
||||
|
||||
- Un flag `isLoading: boolean` global pour une action par item (follow, like, bookmark sur une liste) désactive tous les boutons dès qu'une action est en cours sur un seul item
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Cliquer "Suivre" sur une carte désactive tous les autres boutons "Suivre" de la liste
|
||||
- Impossible de déclencher deux actions en parallèle sur des entités différentes
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
// ❌ Anti-pattern — un seul flag pour toutes les instances
|
||||
followIsLoading: boolean;
|
||||
|
||||
// ✅ Pattern correct — un Set des IDs en cours
|
||||
followingInProgress: Set<string>;
|
||||
|
||||
// Selector
|
||||
isFollowInProgress: (userId: string) => get().followingInProgress.has(userId),
|
||||
|
||||
// Mutation
|
||||
set((state) => {
|
||||
const next = new Set(state.followingInProgress);
|
||||
next.add(targetUserId);
|
||||
return { followingInProgress: next };
|
||||
});
|
||||
// Après succès/erreur
|
||||
next.delete(targetUserId);
|
||||
```
|
||||
|
||||
- Règle : toute action async sur des items d'une liste (like, bookmark, follow, reaction) doit utiliser `Set<EntityId>` au lieu d'un `boolean` global
|
||||
- Contexte technique : React Native / Zustand — app-alexandrie review 5.3, 28-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-erreur-partagee-action-liste"></a>
|
||||
## Clé d'erreur partagée entre action et liste dans un store Zustand
|
||||
|
||||
### Risques
|
||||
|
||||
- Une clé d'erreur partagée entre une mutation (follow/unfollow) et un fetch de liste (followers, followings) affiche une erreur d'action périmée comme erreur de chargement
|
||||
- Ex : `followError: 'ALREADY_FOLLOWING'` stocké depuis une action précédente s'affiche dans l'écran "Abonnés" comme "Erreur de chargement"
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Écran de liste affiche une erreur après une action précédente sans rapport direct
|
||||
- Bug intermittent difficile à reproduire, corrélé à l'ordre des actions utilisateur
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
// ❌ Anti-pattern — clé partagée
|
||||
followError: string | null;
|
||||
|
||||
// ✅ Pattern correct — clés séparées par nature
|
||||
followError: string | null; // erreur de followUser/unfollowUser
|
||||
followersError: string | null; // erreur de fetchFollowers
|
||||
followingsError: string | null; // erreur de fetchFollowings
|
||||
```
|
||||
|
||||
- Règle : dans un store qui gère à la fois des mutations et des listes paginées, chaque opération doit avoir sa propre clé d'erreur
|
||||
- Contexte technique : React Native / Zustand — app-alexandrie review 5.3, 28-03-2026
|
||||
|
||||
Reference in New Issue
Block a user