/** * Enveloppe des API AD — un vide anormal n'est pas un vide (D27) * * Les API AD renvoient `{ entities: [...] }` (D4). Les services lisaient * `response?.entities || []` : toute réponse d'une **autre forme** (pas de * champ `entities`, corps vide, objet d'erreur) devenait un tableau vide, * indistinguable d'une page finale légitime — donc mise en cache avec un * timestamp valide. Un cache vide empoisonné pour tout le TTL, sans le * moindre message. * * Deux cas, deux traitements : * * | Réponse | Traitement | * |---|---| * | `{ entities: [...] }`, y compris `[]` réel | rendue telle quelle — une application peut être légitimement vide (`SmartUI` : 0 workflow, D26) | * | tout le reste | **lève** — l'appel échoue, rien n'est mis en cache, l'appel suivant refetche | * * Volontairement sans retry ni résilience : le but est de rendre l'anomalie * **visible et non persistante**, pas de la rattraper. */ /** * Décrit la forme reçue, pour un message d'erreur exploitable (convention 4). */ function describeShape(response) { if (response === null) return 'null'; if (response === undefined) return 'undefined'; if (Array.isArray(response)) return `un tableau nu de ${response.length} élément(s)`; if (typeof response !== 'object') return `un ${typeof response}`; const keys = Object.keys(response); if (keys.length === 0) return 'un objet vide'; return `un objet sans champ "entities" (champs reçus : ${keys.slice(0, 10).join(', ')})`; } /** * Extrait le tableau `entities` d'une réponse d'API AD, ou lève. * * @param {any} response - la réponse brute de `apiService.post(..., true)` * @param {string} context - l'appel concerné, pour le message d'erreur * (ex. `Workflow/GetByApplication (application "EasyWMS", offset 0)`) * @returns {Array} le tableau `entities`, éventuellement vide * @throws {Error} si la réponse n'a pas la forme `{ entities: [...] }` */ function requireEntities(response, context) { const entities = response ? response.entities : undefined; if (!Array.isArray(entities)) { throw new Error( `Réponse inattendue de l'API AD sur ${context} : ${describeShape(response)}, ` + `au lieu de l'enveloppe attendue { entities: [...] }. ` + `Rien n'a été mis en cache — relancez l'appel. ` + `Si l'erreur persiste, l'API AD est en défaut (elle échoue notamment sous appels concurrents nombreux).` ); } return entities; } module.exports = { requireEntities };