feat: MakerWorld ausfuehrliches Logging fuer Diagnose
This commit is contained in:
@@ -254,36 +254,47 @@ async function attemptLogin(userId, browser, page) {
|
|||||||
async function fetchStatsViaBrowserInner(userId, forceRefresh) {
|
async function fetchStatsViaBrowserInner(userId, forceRefresh) {
|
||||||
const cache = getCache(userId);
|
const cache = getCache(userId);
|
||||||
if (!forceRefresh && cache.data && (Date.now() - cache.fetchedAt) < CACHE_TTL_MS) {
|
if (!forceRefresh && cache.data && (Date.now() - cache.fetchedAt) < CACHE_TTL_MS) {
|
||||||
|
console.log(`[MakerWorld:${userId}] Cache-Treffer, kein Neuabruf (forceRefresh=false)`);
|
||||||
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: false };
|
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: false };
|
||||||
}
|
}
|
||||||
if (pendingLoginByUser.has(userId)) {
|
if (pendingLoginByUser.has(userId)) {
|
||||||
|
console.log(`[MakerWorld:${userId}] Noch ein offener Login-Vorgang (wartet auf Code) — Abruf übersprungen`);
|
||||||
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: true };
|
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
try {
|
try {
|
||||||
|
console.log(`[MakerWorld:${userId}] Abruf gestartet (forceRefresh=${forceRefresh})`);
|
||||||
browser = await launchBrowser(userId);
|
browser = await launchBrowser(userId);
|
||||||
|
console.log(`[MakerWorld:${userId}] Browser gestartet, öffne Seite`);
|
||||||
page = await browser.newPage();
|
page = await browser.newPage();
|
||||||
await page.setUserAgent(USER_AGENT);
|
await page.setUserAgent(USER_AGENT);
|
||||||
await page.setViewport({ width: 1366, height: 900 });
|
await page.setViewport({ width: 1366, height: 900 });
|
||||||
await page.goto(DATA_URL, { waitUntil: 'networkidle2', timeout: 45000 });
|
await page.goto(DATA_URL, { waitUntil: 'networkidle2', timeout: 45000 });
|
||||||
|
console.log(`[MakerWorld:${userId}] Seite geladen: "${await page.title().catch(()=>'?')}" (${page.url()})`);
|
||||||
|
|
||||||
// Bis zu 20 Sekunden Zeit geben, falls Cloudflare eine automatische
|
// Bis zu 20 Sekunden Zeit geben, falls Cloudflare eine automatische
|
||||||
// Managed-Challenge zeigt (löst sich bei echtem Chromium meist selbst)
|
// Managed-Challenge zeigt (löst sich bei echtem Chromium meist selbst)
|
||||||
|
let cfWaited = 0;
|
||||||
for (let i = 0; i < 5 && await isCloudflareChallenge(page); i++) {
|
for (let i = 0; i < 5 && await isCloudflareChallenge(page); i++) {
|
||||||
|
cfWaited += 4;
|
||||||
|
console.log(`[MakerWorld:${userId}] Cloudflare-Challenge erkannt, warte weiter (${cfWaited}s)...`);
|
||||||
await new Promise(r => setTimeout(r, 4000));
|
await new Promise(r => setTimeout(r, 4000));
|
||||||
}
|
}
|
||||||
|
|
||||||
let parsed = await getNextDataFromPage(page);
|
let parsed = await getNextDataFromPage(page);
|
||||||
|
console.log(`[MakerWorld:${userId}] __NEXT_DATA__ ${parsed ? 'gefunden' : 'NICHT gefunden'}`);
|
||||||
|
|
||||||
if (!parsed && isLoginUrl(page.url())) {
|
if (!parsed && isLoginUrl(page.url())) {
|
||||||
|
console.log(`[MakerWorld:${userId}] Login-Seite erkannt (${page.url()}), versuche automatischen Login`);
|
||||||
parsed = await attemptLogin(userId, browser, page); // wirft ggf. needsCode-Error
|
parsed = await attemptLogin(userId, browser, page); // wirft ggf. needsCode-Error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
const debugTitle = await page.title().catch(() => '?');
|
const debugTitle = await page.title().catch(() => '?');
|
||||||
const debugUrl = page.url();
|
const debugUrl = page.url();
|
||||||
|
console.log(`[MakerWorld:${userId}] Fehlschlag — Seite: "${debugTitle}" (${debugUrl})`);
|
||||||
await saveDebugScreenshot(userId, page).catch(() => {});
|
await saveDebugScreenshot(userId, page).catch(() => {});
|
||||||
throw new Error(`__NEXT_DATA__ nicht gefunden — Seite: "${debugTitle}" (${debugUrl}). Debug-Screenshot verfügbar über GET /debug-screenshot`);
|
throw new Error(`__NEXT_DATA__ nicht gefunden — Seite: "${debugTitle}" (${debugUrl}). Debug-Screenshot verfügbar über GET /debug-screenshot`);
|
||||||
}
|
}
|
||||||
@@ -291,11 +302,14 @@ async function fetchStatsViaBrowserInner(userId, forceRefresh) {
|
|||||||
const data = mapStatisticalData(parsed);
|
const data = mapStatisticalData(parsed);
|
||||||
cache.data = data; cache.fetchedAt = Date.now(); cache.error = null;
|
cache.data = data; cache.fetchedAt = Date.now(); cache.error = null;
|
||||||
await browser.close();
|
await browser.close();
|
||||||
|
console.log(`[MakerWorld:${userId}] Erfolgreich: ${data.downloads} Downloads, ${data.likes} Likes`);
|
||||||
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: false };
|
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: false };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.needsCode) {
|
if (e.needsCode) {
|
||||||
|
console.log(`[MakerWorld:${userId}] Code-Eingabe erforderlich, Browser bleibt offen`);
|
||||||
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: true };
|
return { data: cache.data, error: null, fetchedAt: cache.fetchedAt, needsCode: true };
|
||||||
}
|
}
|
||||||
|
console.error(`[MakerWorld:${userId}] Fehler: ${e.message}`);
|
||||||
if (browser) await browser.close().catch(() => {});
|
if (browser) await browser.close().catch(() => {});
|
||||||
cache.error = e.message;
|
cache.error = e.message;
|
||||||
return { data: cache.data, error: cache.error, fetchedAt: cache.fetchedAt, needsCode: false };
|
return { data: cache.data, error: cache.error, fetchedAt: cache.fetchedAt, needsCode: false };
|
||||||
@@ -340,15 +354,21 @@ async function submitLoginCodeInner(userId, code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function injectCookiesInner(userId, cookieString) {
|
async function injectCookiesInner(userId, cookieString) {
|
||||||
|
console.log(`[MakerWorld:${userId}] Cookie-Injection gestartet (${cookieString.length} Zeichen)`);
|
||||||
const cookies = cookieString.split(';').map(s => s.trim()).filter(Boolean).map(p => {
|
const cookies = cookieString.split(';').map(s => s.trim()).filter(Boolean).map(p => {
|
||||||
const idx = p.indexOf('=');
|
const idx = p.indexOf('=');
|
||||||
return { name: p.slice(0, idx), value: p.slice(idx + 1), domain: '.makerworld.com', path: '/' };
|
return { name: p.slice(0, idx), value: p.slice(idx + 1), domain: '.makerworld.com', path: '/' };
|
||||||
});
|
});
|
||||||
|
console.log(`[MakerWorld:${userId}] ${cookies.length} Cookies geparst: ${cookies.map(c=>c.name).join(', ')}`);
|
||||||
const browser = await launchBrowser(userId);
|
const browser = await launchBrowser(userId);
|
||||||
|
console.log(`[MakerWorld:${userId}] Browser für Cookie-Injection gestartet`);
|
||||||
try {
|
try {
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.goto('https://makerworld.com', { waitUntil: 'domcontentloaded', timeout: 20000 }).catch(() => {});
|
await page.goto('https://makerworld.com', { waitUntil: 'domcontentloaded', timeout: 20000 }).catch((e) => {
|
||||||
|
console.log(`[MakerWorld:${userId}] Navigation vor Cookie-Set fehlgeschlagen (ignoriert): ${e.message}`);
|
||||||
|
});
|
||||||
await page.setCookie(...cookies);
|
await page.setCookie(...cookies);
|
||||||
|
console.log(`[MakerWorld:${userId}] Cookies gesetzt, schließe Browser`);
|
||||||
} finally {
|
} finally {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
}
|
}
|
||||||
@@ -455,14 +475,17 @@ router.delete('/credentials', authenticate, (req, res) => {
|
|||||||
// Manueller Fallback: Cookie-String direkt ins eigene Profil einspielen
|
// Manueller Fallback: Cookie-String direkt ins eigene Profil einspielen
|
||||||
router.post('/cookie', authenticate, async (req, res) => {
|
router.post('/cookie', authenticate, async (req, res) => {
|
||||||
const { cookie } = req.body;
|
const { cookie } = req.body;
|
||||||
|
console.log(`[MakerWorld:${req.user.id}] POST /cookie empfangen (${cookie?.length || 0} Zeichen)`);
|
||||||
if (!cookie || typeof cookie !== 'string' || cookie.trim().length < 10) {
|
if (!cookie || typeof cookie !== 'string' || cookie.trim().length < 10) {
|
||||||
return res.status(400).json({ error: 'Ungültiger Cookie-String' });
|
return res.status(400).json({ error: 'Ungültiger Cookie-String' });
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await injectCookies(req.user.id, cookie.trim());
|
await injectCookies(req.user.id, cookie.trim());
|
||||||
const result = await fetchStatsViaBrowser(req.user.id, true);
|
const result = await fetchStatsViaBrowser(req.user.id, true);
|
||||||
|
console.log(`[MakerWorld:${req.user.id}] POST /cookie fertig: needsCode=${result.needsCode}, error=${result.error||'-'}`);
|
||||||
res.json(result);
|
res.json(result);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(`[MakerWorld:${req.user.id}] POST /cookie Exception: ${e.message}`);
|
||||||
res.status(500).json({ error: e.message });
|
res.status(500).json({ error: e.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user