This commit is contained in:
2026-04-21 14:31:59 +00:00
parent c6edc5c0bf
commit 74d7f49c8d
12 changed files with 125 additions and 28 deletions

View File

@@ -33,7 +33,10 @@ let authErrorNotified = false;
let pollSuspended = false;
let pollCount = 0, totalProcessed = 0, totalSkipped = 0, totalErrors = 0;
function setPollSuspended(val) { pollSuspended = !!val; }
function setPollSuspended(val) {
pollSuspended = !!val;
if (!pollSuspended) authErrorNotified = false;
}
function isPollSuspended() { return pollSuspended; }
/**
@@ -362,18 +365,16 @@ async function poll(client) {
}
authErrorNotified = false;
} catch (e) {
const isAuthError =
(e.message && (
e.message.includes('invalid_grant') ||
e.message.includes('unauthorized') ||
e.message.includes('Invalid Credentials')
)) ||
e.status === 401 ||
e.code === 401;
// Only treat Google-reported permanent-grant failures as reasons to suspend
// the loop. Transient 401/403/429/5xx/network errors fall through to the
// next interval tick naturally. The OAuth error codes come back on the
// response body, not the message string.
const oauthError = e && e.response && e.response.data && e.response.data.error;
const isPermanentAuth = oauthError === 'invalid_grant' || oauthError === 'invalid_client';
if (isAuthError) {
if (isPermanentAuth) {
pollSuspended = true;
const suspendMsg = 'Gmail OAuth token invalid or expired. Polling SUSPENDED — will not retry automatically. Re-authenticate to resume.';
const suspendMsg = `Gmail OAuth ${oauthError}. Polling SUSPENDED — will not retry automatically. Re-authenticate and POST /internal/gmail/reload to resume.`;
console.error('[gmail-poll]', suspendMsg);
logError('Gmail OAuth', { message: suspendMsg, stack: e.stack || e.message || String(e) }, null, client).catch(() => {});
try { require('./broccolini-discord').clearGmailPollInterval?.(); } catch (_) {}