From b19a1673067c0d90a517e3cd942c31654808a492 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Sat, 30 May 2026 14:14:07 -0500 Subject: [PATCH] race condition --- qbo_helper.js | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/qbo_helper.js b/qbo_helper.js index 2cde3ce..ebfd095 100644 --- a/qbo_helper.js +++ b/qbo_helper.js @@ -15,6 +15,7 @@ const path = require('path'); let oauthClient = null; let _lastSavedAccessToken = null; +let refreshInFlight = null; // single-flight lock for concurrent token refresh const tokenFile = path.join(__dirname, 'qbo_token.json'); const getOAuthClient = () => { @@ -110,25 +111,34 @@ async function makeQboApiCall(requestOptions) { } const doRefresh = async () => { + if (refreshInFlight) { + console.log(`[${ts()}] ⏳ Awaiting in-flight token refresh...`); + return refreshInFlight; + } console.log(`[${ts()}] 🔄 QBO Token Refresh...`); const refreshTokenStr = currentToken.refresh_token; - try { - const authResponse = await client.refreshUsingToken(refreshTokenStr); - console.log(`[${ts()}] ✅ Token refreshed via refreshUsingToken()`); - saveTokens(); // saveTokens prüft selbst ob sich was geändert hat - return authResponse; - } catch (e) { - const errMsg = e.originalMessage || e.message || String(e); - console.error(`[${ts()}] ❌ Refresh failed: ${errMsg}`); - if (e.intuit_tid) console.error(` intuit_tid: ${e.intuit_tid}`); - if (errMsg.includes('invalid_grant')) { - throw new Error( - "Der Refresh Token ist bei Intuit ungültig (invalid_grant). " + - "Bitte im Playground einen neuen Token holen und set_qbo_token.js ausführen." - ); + refreshInFlight = (async () => { + try { + const authResponse = await client.refreshUsingToken(refreshTokenStr); + console.log(`[${ts()}] ✅ Token refreshed via refreshUsingToken()`); + saveTokens(); + return authResponse; + } catch (e) { + const errMsg = e.originalMessage || e.message || String(e); + console.error(`[${ts()}] ❌ Refresh failed: ${errMsg}`); + if (e.intuit_tid) console.error(` intuit_tid: ${e.intuit_tid}`); + if (errMsg.includes('invalid_grant')) { + throw new Error( + "Der Refresh Token ist bei Intuit ungültig (invalid_grant). " + + "Bitte im Playground einen neuen Token holen und set_qbo_token.js ausführen." + ); + } + throw e; + } finally { + refreshInFlight = null; } - throw e; - } + })(); + return refreshInFlight; }; try {