From b74febe1282e9081a509ef36d3811ee5311dc67f Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Wed, 8 Jun 2022 07:49:45 +0000 Subject: [PATCH] [IMP] web: stop using guardedCatch in Mutex Guarded catch promotes bad patterns (using promise rejections as control flow instead of as errors), as such, we should not use it in non-legacy code. This commit reworks the exec method of the Mutex utility class to avoid using it. closes odoo/odoo#93081 Signed-off-by: Aaron Bohy (aab) --- .../web/static/src/core/utils/concurrency.js | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/addons/web/static/src/core/utils/concurrency.js b/addons/web/static/src/core/utils/concurrency.js index 78c5349afaa..b673cb6b8b4 100644 --- a/addons/web/static/src/core/utils/concurrency.js +++ b/addons/web/static/src/core/utils/concurrency.js @@ -83,31 +83,24 @@ export class Mutex { * @returns {Promise} */ async exec(action) { - const currentLock = this._lock; - let result; this._queueSize++; - this._unlockedProm = - this._unlockedProm || - new Promise((resolve) => { - this._unlock = resolve; - }); - this._lock = new Promise((unlockCurrent) => { - currentLock.then(() => { - result = action(); - const always = (returnedResult) => { - unlockCurrent(); - this._queueSize--; - if (this._queueSize === 0) { - this._unlockedProm = undefined; - this._unlock(); - } - return returnedResult; + if (!this._unlockedProm) { + this._unlockedProm = new Promise((resolve) => { + this._unlock = () => { + resolve(); + this._unlockedProm = undefined; }; - Promise.resolve(result).then(always).guardedCatch(always); }); - }); - await this._lock; - return result; + } + const always = () => { + return Promise.resolve(action()).finally(() => { + if (--this._queueSize === 0) { + this._unlock(); + } + }); + }; + this._lock = this._lock.then(always, always); + return this._lock; } /** * @returns {Promise} resolved as soon as the Mutex is unlocked