From 593117a639ca4f45d082dea97c47a7351189bade Mon Sep 17 00:00:00 2001 From: Oleg Valter Date: Thu, 11 Dec 2025 09:34:51 +0300 Subject: [PATCH] fixed QPixel#user race conditions --- app/assets/javascripts/qpixel_api.js | 40 +++++++++++++--------------- global.d.ts | 4 +-- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/app/assets/javascripts/qpixel_api.js b/app/assets/javascripts/qpixel_api.js index 681c93b61..51a9336e6 100644 --- a/app/assets/javascripts/qpixel_api.js +++ b/app/assets/javascripts/qpixel_api.js @@ -110,9 +110,9 @@ window.QPixel = { /** * Used to prevent launching multiple requests to /users/me - * @type {Promise|null} + * @type {Promise|null} */ - _pendingUserResponse: null, + _pendingUser: null, /** * @type {QPixelUser|null} @@ -120,18 +120,24 @@ window.QPixel = { _user: null, _fetchUser () { - if (QPixel._pendingUserResponse) { - return QPixel._pendingUserResponse; + if (QPixel._pendingUser) { + return QPixel._pendingUser; } - const myselfPromise = QPixel.fetch('/users/me', { - headers: { - 'Accept': 'application/json', - 'Cache-Control': 'no-cache', - } - }); + const myselfPromise = QPixel + .fetch('/users/me', { + headers: { + 'Accept': 'application/json', + 'Cache-Control': 'no-cache', + } + }) + .then((resp) => resp.json()) + .catch(() => null) + .finally(() => { + QPixel._pendingUser = null; + }); - QPixel._pendingUserResponse = myselfPromise; + QPixel._pendingUser = myselfPromise; return myselfPromise; }, @@ -141,17 +147,7 @@ window.QPixel = { return QPixel._user; } - try { - const resp = await QPixel._fetchUser(); - - if (!resp.bodyUsed) { - QPixel._user = await resp.json(); - } - } - finally { - // ensures pending user is cleared regardless of network errors - QPixel._pendingUserResponse = null; - } + QPixel._user = await QPixel._fetchUser(); return QPixel._user; }, diff --git a/global.d.ts b/global.d.ts index e53bd3b24..0153e8907 100644 --- a/global.d.ts +++ b/global.d.ts @@ -364,7 +364,7 @@ interface QPixel { // private properties _filters?: QPixelFilter[] | null; - _pendingUserResponse?: Promise | null; + _pendingUser?: Promise | null; _popups?: Record; _preferences?: UserPreferences | null; _user?: QPixelUser | null; @@ -384,7 +384,7 @@ interface QPixel { /** * FIFO-style fetch wrapper for /users/me requests */ - _fetchUser?: () => Promise; + _fetchUser?: () => Promise; /** * Get an object containing the current user's preferences. Loads, in order of precedence, from local variable,