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
All checks were successful
build-and-push-ext / build_push (push) Successful in 23s
This commit is contained in:
parent
2d0d77be1c
commit
0c74cccc04
@ -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
|
## v1.0.7
|
||||||
|
|
||||||
- IdNot: correction endpoint API Annuaire selon documentation (`/api/pp/v2/personnes/{id}/rattachements`)
|
- IdNot: correction endpoint API Annuaire selon documentation (`/api/pp/v2/personnes/{id}/rattachements`)
|
||||||
|
@ -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.
|
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
|
### Observabilité IdNot
|
||||||
- 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.
|
- 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
|
### Dépendances clés
|
||||||
- **HTTP**: `express`, `cors`
|
- **HTTP**: `express`, `cors`
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lecoffre-back-mini",
|
"name": "lecoffre-back-mini",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"description": "Mini serveur avec une route /api/ping",
|
"description": "Mini serveur avec une route /api/ping",
|
||||||
"main": "dist/server.js",
|
"main": "dist/server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -59,27 +59,73 @@ export class IdNotService {
|
|||||||
throw new Error('Missing IDnot API key or annuary base URL');
|
throw new Error('Missing IDnot API key or annuary base URL');
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchParams = new URLSearchParams({
|
// Essayer plusieurs variantes d'endpoints et paramètres
|
||||||
key: IDNOT_API_KEY,
|
const endpoints = [
|
||||||
deleted: 'false'
|
// 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];
|
||||||
if (!response.ok) {
|
const searchParams = searchParamsVariants[i];
|
||||||
const text = await response.text().catch(() => '');
|
const url = `${baseUrl}?${searchParams}`;
|
||||||
Logger.error('IdNot getUserRattachements failed', {
|
|
||||||
url,
|
try {
|
||||||
status: response.status,
|
Logger.info(`IdNot getUserRattachements attempt ${i + 1}`, { url, idNot });
|
||||||
statusText: response.statusText,
|
|
||||||
bodySnippet: text?.substring(0, 500)
|
const response = await fetch(url, { method: 'GET' });
|
||||||
});
|
|
||||||
throw new Error(`Failed to fetch rattachements: ${response.status} ${response.statusText}`);
|
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) {
|
static async getOfficeRattachements(idNot: string) {
|
||||||
|
@ -24,4 +24,10 @@ Focus régression v1.0.3:
|
|||||||
- Cas « utilisateur non rattaché à une étude » doit renvoyer `403` (plus de 502).
|
- Cas « utilisateur non rattaché à une étude » doit renvoyer `403` (plus de 502).
|
||||||
|
|
||||||
### Traces attendues (v1.0.4)
|
### Traces attendues (v1.0.4)
|
||||||
- En cas d’échec IdNot, vérifier la présence d’un 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user