fix(mail): BigInt-Serialisierung blockierte Phase-2-Persistierung
imapflow.status() liefert uidValidity als BigInt. Der Code reichte den BigInt in
JSON.stringify (patchFolderScanState) → 'TypeError: Do not know how to serialize
a BigInt' → vom stummen connection-level catch verschluckt → weder
patchFolderScanState noch markFullSweepDone liefen je → folder_scan_state blieb
{} + last_full_sweep_at NULL → inkrementeller Scan aktivierte nie (immer Full-Sweep).
Fix:
- serverUidValidity: Number((status).uidValidity ?? 0) — BigInt → number vor JSON.
- Stumme catches (auth/lock/conn) loggen jetzt; Persist-Calls (patchFolderScanState
x2, markFullSweepDone) in eigene try/catch mit console.error — Diagnostik bleibt
drin für Post-Deploy-Verify.
Lokal verifiziert: Build EXIT 0, imapflow extern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
cc549c7f17
commit
1f73bd8d8d
@ -78,7 +78,8 @@ export default defineEventHandler(async (event) => {
|
||||
let imapAuth: { user: string; accessToken: string } | { user: string; pass: string };
|
||||
try {
|
||||
imapAuth = await resolveImapAuth(connection, oauthClientIds);
|
||||
} catch {
|
||||
} catch (authErr) {
|
||||
console.error(`[scan-internal] resolveImapAuth failed for ${connection.email}:`, authErr);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -136,7 +137,8 @@ export default defineEventHandler(async (event) => {
|
||||
let lock: any;
|
||||
try {
|
||||
lock = await imap.getMailboxLock(mb.path);
|
||||
} catch {
|
||||
} catch (lockErr) {
|
||||
console.warn(`[scan-internal] ${connection.email} | ${mb.path} | getMailboxLock failed, skipping folder:`, lockErr);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
@ -149,16 +151,25 @@ export default defineEventHandler(async (event) => {
|
||||
uidValidity: true,
|
||||
});
|
||||
const msgCount = (status as any).messages ?? 0;
|
||||
const serverUidValidity: number = (status as any).uidValidity ?? 0;
|
||||
// imapflow liefert uidValidity als BigInt (IMAP-Spec: 32-bit unsigned).
|
||||
// Number() konvertiert BigInt sicher — UIDVALIDITY ist max 2^32-1, weit unter
|
||||
// Number.MAX_SAFE_INTEGER (2^53-1), kein Präzisionsverlust möglich.
|
||||
// Ohne Number() würde JSON.stringify({uidvalidity: BigInt(x)}) werfen und
|
||||
// patchFolderScanState still crashen (verschluckt vom äußeren catch {}).
|
||||
const serverUidValidity: number = Number((status as any).uidValidity ?? 0);
|
||||
|
||||
if (msgCount === 0) {
|
||||
// Ordner leer — trotzdem Zustand für diesen Ordner persistieren
|
||||
// (verhindert endloses Re-Fetching auf leere Ordner).
|
||||
if (serverUidValidity > 0) {
|
||||
await patchFolderScanState(connection.id, mb.path, {
|
||||
lastUid: 0,
|
||||
uidvalidity: serverUidValidity,
|
||||
});
|
||||
try {
|
||||
await patchFolderScanState(connection.id, mb.path, {
|
||||
lastUid: 0,
|
||||
uidvalidity: serverUidValidity,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`[scan-internal] persist failed — patchFolderScanState(${mb.path}, empty folder):`, e);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -353,10 +364,14 @@ export default defineEventHandler(async (event) => {
|
||||
}, 0);
|
||||
|
||||
if (maxUid > 0 && serverUidValidity > 0) {
|
||||
await patchFolderScanState(connection.id, mb.path, {
|
||||
lastUid: maxUid,
|
||||
uidvalidity: serverUidValidity,
|
||||
});
|
||||
try {
|
||||
await patchFolderScanState(connection.id, mb.path, {
|
||||
lastUid: maxUid,
|
||||
uidvalidity: serverUidValidity,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`[scan-internal] persist failed — patchFolderScanState(${mb.path}, maxUid=${maxUid}, uidvalidity=${serverUidValidity}):`, e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.release();
|
||||
@ -365,12 +380,17 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
// ─── Full-Sweep abschließen ─────────────────────────────────────────────
|
||||
if (needsFullSweep) {
|
||||
await markFullSweepDone(connection.id);
|
||||
console.log(`[scan-internal] ${connection.email} | full-sweep complete, lastFullSweepAt updated`);
|
||||
try {
|
||||
await markFullSweepDone(connection.id);
|
||||
console.log(`[scan-internal] ${connection.email} | full-sweep complete, lastFullSweepAt updated`);
|
||||
} catch (e) {
|
||||
console.error(`[scan-internal] persist failed — markFullSweepDone(${connection.id}):`, e);
|
||||
}
|
||||
}
|
||||
|
||||
await imap.logout();
|
||||
} catch {
|
||||
} catch (connErr) {
|
||||
console.error(`[scan-internal] connection-level error for ${connection.email}:`, connErr);
|
||||
try {
|
||||
await imap.logout();
|
||||
} catch {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user