async function mouvRequestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const res = await fetch(url, options);
// Éxito
if (res.ok) return res.json();
const body = await res.json();
// Errores que NO se reintenan
if (res.status === 400 || res.status === 401 || res.status === 403 || res.status === 422) {
throw new Error(body.error);
}
// Rate limit: respect Retry-After
if (res.status === 429) {
const wait = parseInt(res.headers.get('Retry-After') || '1') * 1000;
await new Promise(r => setTimeout(r, wait));
continue;
}
// 5xx: backoff exponencial
if (res.status >= 500) {
const wait = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(r => setTimeout(r, wait));
continue;
}
}
throw new Error('MAX_RETRIES_EXCEEDED');
}