fix(sync): 403 InnerTube = version client inventée; aligne WEB 2.20260623.01.00 + expose ytReason

This commit is contained in:
2026-09-26 23:01:10 -04:00
parent 5a19f8f11f
commit 41875dc50d
3 changed files with 13 additions and 3 deletions
+1
View File
@@ -716,6 +716,7 @@ r.get('/oauth/google/yt-history', authMiddlewareCookieAware, oauthLimiter, async
return res.json({ items, count: items.length, hasMore });
} catch (error) {
const out = { error: error?.message || 'ythistory_fetch_failed' };
if (error?.ytReason) out.ytReason = error.ytReason;
if (error?.status === 401) {
out.hint = 'Session Google expirée : déconnectez puis reconnectez Google.';
}
+9 -2
View File
@@ -506,7 +506,12 @@ async function innertubePost(path, apiKey, accessToken, body, label = 'innertube
if (!resp.ok) {
const err = new Error(`${label}_failed_${resp.status}`);
err.status = resp.status === 401 ? 401 : resp.status;
err.details = data?.error || undefined;
// Motif YouTube (sans PII) pour diagnostiquer : ex. rateLimitExceeded,
// botGuard, authError... remonte jusqu'à l'UI.
try {
const e0 = data?.error?.errors?.[0] || {};
err.ytReason = String(e0.reason || data?.error?.message || '').slice(0, 160) || undefined;
} catch {}
throw err;
}
return data;
@@ -522,7 +527,9 @@ async function innertubePost(path, apiKey, accessToken, body, label = 'innertube
}
function innertubeContext() {
return { client: { clientName: 'WEB', clientVersion: '2.20260101.00.00', hl: 'fr', gl: 'FR' } };
// Version du client WEB alignée sur youtubei.js (dépendance du projet) :
// une version inconnue/inventée est rejetée en 403 par l'anti-bot.
return { client: { clientName: 'WEB', clientVersion: '2.20260623.01.00', hl: 'fr', gl: 'FR' } };
}
/** Boucle browse + continuations générique (FEhistory, WL, ...). */
@@ -157,7 +157,9 @@ export class ImportComponent implements OnInit {
} catch (e: any) {
const code = e?.error?.error || e?.message || 'ythistory_fetch_failed';
const hint = e?.error?.hint;
this.ytAutoError.set(hint ? `${code} — ${hint}` : code);
const ytReason = e?.error?.ytReason;
const extra = [hint, ytReason ? `YouTube: ${ytReason}` : ''].filter(Boolean).join(' — ');
this.ytAutoError.set(extra ? `${code} — ${extra}` : code);
} finally {
this.ytAutoLoading.set(false);
}