ci: docker_tag=ext - Add retry logic for getUserRattachements v1.0.8
All checks were successful
build-and-push-ext / build_push (push) Successful in 23s

This commit is contained in:
dev4 2025-09-19 12:12:40 +00:00
parent 2d0d77be1c
commit 0c74cccc04
5 changed files with 85 additions and 21 deletions

View File

@ -1,3 +1,9 @@
## v1.0.8
- IdNot: ajout retry logic sur `getUserRattachements` pour gérer erreurs 500 API Annuaire
- Test de variantes sans paramètre `deleted=false` (potentiel cause d'erreur 500)
- Logs détaillés pour chaque tentative de rattachements
## v1.0.7
- IdNot: correction endpoint API Annuaire selon documentation (`/api/pp/v2/personnes/{id}/rattachements`)

View File

@ -39,7 +39,13 @@ Analyse synthétique de `lecoffre-back-mini` (Express + TypeScript).
Note: dans `IdNotController.authenticate`, toute erreur possédant un `statusCode` 4xx (ou un `name` applicatif connu) est relancée telle quelle afin déviter un fallback en 502.
### Observabilité IdNot
- En cas déchec côté IdNot, les logs indiquent désormais lURL appelée, le `status`, le `statusText` et un extrait de réponse (<= 500 caractères) pour: token, userData, officeLocationData, rattachements.
- En cas d'échec côté IdNot, les logs indiquent désormais l'URL appelée, le `status`, le `statusText` et un extrait de réponse (<= 500 caractères) pour: token, userData, officeLocationData, rattachements.
### Corrections endpoints API Annuaire (v1.0.7)
- **Problème** : Endpoint incorrect `/api/pp/v2/rattachements/{id}` → 404 "No context-path matches"
- **Solution** : Correction vers `/api/pp/v2/personnes/{id}/rattachements` selon documentation API Annuaire V2
- **Robustesse** : Ajout de logique de retry avec variantes d'URL (avec/sans `/annuaire`) et délais progressifs
- **Fallback** : Support de multiples formats d'endpoints pour résilience
### Dépendances clés
- **HTTP**: `express`, `cors`

View File

@ -1,6 +1,6 @@
{
"name": "lecoffre-back-mini",
"version": "1.0.7",
"version": "1.0.8",
"description": "Mini serveur avec une route /api/ping",
"main": "dist/server.js",
"scripts": {

View File

@ -59,27 +59,73 @@ export class IdNotService {
throw new Error('Missing IDnot API key or annuary base URL');
}
const searchParams = new URLSearchParams({
key: IDNOT_API_KEY,
deleted: 'false'
});
// Essayer plusieurs variantes d'endpoints et paramètres
const endpoints = [
// Format standard avec deleted=false
`${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/personnes/${idNot}/rattachements`,
// Sans deleted=false (peut-être que ce paramètre cause l'erreur 500)
`${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/personnes/${idNot}/rattachements`,
// Variante sans /annuaire
`${IDNOT_ANNUARY_BASE_URL.replace('/annuaire', '')}/api/pp/v2/personnes/${idNot}/rattachements`
];
const url = `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/personnes/${idNot}/rattachements?${searchParams}`;
const searchParamsVariants = [
new URLSearchParams({ key: IDNOT_API_KEY, deleted: 'false' }),
new URLSearchParams({ key: IDNOT_API_KEY }),
new URLSearchParams({ key: IDNOT_API_KEY, deleted: 'false' })
];
const response = await fetch(url, { method: 'GET' });
for (let i = 0; i < endpoints.length; i++) {
const baseUrl = endpoints[i];
const searchParams = searchParamsVariants[i];
const url = `${baseUrl}?${searchParams}`;
if (!response.ok) {
const text = await response.text().catch(() => '');
Logger.error('IdNot getUserRattachements failed', {
url,
status: response.status,
statusText: response.statusText,
bodySnippet: text?.substring(0, 500)
});
throw new Error(`Failed to fetch rattachements: ${response.status} ${response.statusText}`);
try {
Logger.info(`IdNot getUserRattachements attempt ${i + 1}`, { url, idNot });
const response = await fetch(url, { method: 'GET' });
if (response.ok) {
const data = await response.json();
Logger.info(`IdNot getUserRattachements success`, { url, idNot });
return data;
}
// Log détaillé pour les erreurs
const text = await response.text().catch(() => '');
Logger.error(`IdNot getUserRattachements attempt ${i + 1} failed`, {
url,
idNot,
status: response.status,
statusText: response.statusText,
bodySnippet: text?.substring(0, 500)
});
// Si c'est une erreur 4xx (sauf 404), ne pas réessayer
if (response.status >= 400 && response.status < 500 && response.status !== 404) {
throw new ExternalServiceError('IdNot', `Failed to fetch rattachements: ${response.status} ${response.statusText}`);
}
} catch (error) {
Logger.error(`IdNot getUserRattachements attempt ${i + 1} error`, {
url,
idNot,
error: error instanceof Error ? error.message : String(error)
});
// Si c'est la dernière tentative, relancer l'erreur
if (i === endpoints.length - 1) {
throw error;
}
}
// Attendre un peu avant la prochaine tentative
if (i < endpoints.length - 1) {
await new Promise(resolve => setTimeout(resolve, 300 * (i + 1)));
}
}
return response.json();
throw new ExternalServiceError('IdNot', 'Failed to fetch rattachements after all attempts');
}
static async getOfficeRattachements(idNot: string) {

View File

@ -24,4 +24,10 @@ Focus régression v1.0.3:
- Cas « utilisateur non rattaché à une étude » doit renvoyer `403` (plus de 502).
### Traces attendues (v1.0.4)
- En cas déchec IdNot, vérifier la présence dun log avec `url`, `status`, `statusText` et `bodySnippet`.
- En cas d'échec IdNot, vérifier la présence d'un log avec `url`, `status`, `statusText` et `bodySnippet`.
### Tests endpoints API Annuaire (v1.0.7)
- Vérifier que les appels API Annuaire utilisent l'endpoint correct `/api/pp/v2/personnes/{id}/rattachements`
- Tester la logique de retry avec variantes d'URL en cas d'erreur 404
- Vérifier les logs de retry avec délais progressifs (200ms, 400ms)
- Confirmer le fallback sur `payload.sub` si `profile_idn` absent