From 06793299eff7d9256477b1e1250dd09de67ada81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 19 Jun 2023 08:52:59 +0200 Subject: [PATCH] Fix handling of sync error in `@@asyncDispose` (#15705) * Reduce recursion when disposing sync resources * Fix handling of sync error in `@@asyncDispose` * Make the generated helper slightly smaller --- .../babel-helpers/src/helpers-generated.ts | 2 +- packages/babel-helpers/src/helpers/dispose.js | 23 ++++++++----------- .../async-dispose-throws-synchronously.js | 9 +++++--- .../babel-runtime-corejs3/helpers/dispose.js | 15 +++++------- packages/babel-runtime/helpers/dispose.js | 15 +++++------- 5 files changed, 28 insertions(+), 36 deletions(-) diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index 493302fc1e15..eb66c6bbc1a7 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -63,7 +63,7 @@ export default Object.freeze({ ), dispose: helper( "7.22.0", - 'function dispose_SuppressedError(suppressed,error){return"undefined"!=typeof SuppressedError?dispose_SuppressedError=SuppressedError:(dispose_SuppressedError=function(suppressed,error){this.suppressed=suppressed,this.error=error,this.stack=(new Error).stack},dispose_SuppressedError.prototype=Object.create(Error.prototype,{constructor:{value:dispose_SuppressedError,writable:!0,configurable:!0}})),new dispose_SuppressedError(suppressed,error)}export default function _dispose(stack,error,hasError){function next(){if(0!==stack.length){var r=stack.pop();if(r.a)return Promise.resolve(r.d.call(r.v)).then(next,err);try{r.d.call(r.v)}catch(e){return err(e)}return next()}if(hasError)throw error}function err(e){return error=hasError?new dispose_SuppressedError(e,error):e,hasError=!0,next()}return next()}', + 'function dispose_SuppressedError(suppressed,error){return"undefined"!=typeof SuppressedError?dispose_SuppressedError=SuppressedError:(dispose_SuppressedError=function(suppressed,error){this.suppressed=suppressed,this.error=error,this.stack=(new Error).stack},dispose_SuppressedError.prototype=Object.create(Error.prototype,{constructor:{value:dispose_SuppressedError,writable:!0,configurable:!0}})),new dispose_SuppressedError(suppressed,error)}export default function _dispose(stack,error,hasError){function next(){for(;stack.length>0;)try{var r=stack.pop(),p=r.d.call(r.v);if(r.a)return Promise.resolve(p).then(next,err)}catch(e){return err(e)}if(hasError)throw error}function err(e){return error=hasError?new dispose_SuppressedError(e,error):e,hasError=!0,next()}return next()}', ), iterableToArrayLimit: helper( "7.0.0-beta.0", diff --git a/packages/babel-helpers/src/helpers/dispose.js b/packages/babel-helpers/src/helpers/dispose.js index 7bcde7eeba0f..33677b7ca783 100644 --- a/packages/babel-helpers/src/helpers/dispose.js +++ b/packages/babel-helpers/src/helpers/dispose.js @@ -22,21 +22,16 @@ function dispose_SuppressedError(suppressed, error) { export default function _dispose(stack, error, hasError) { function next() { - if (stack.length === 0) { - if (hasError) throw error; - return; + while (stack.length > 0) { + try { + var r = stack.pop(); + var p = r.d.call(r.v); + if (r.a) return Promise.resolve(p).then(next, err); + } catch (e) { + return err(e); + } } - - var r = stack.pop(); - if (r.a) { - return Promise.resolve(r.d.call(r.v)).then(next, err); - } - try { - r.d.call(r.v); - } catch (e) { - return err(e); - } - return next(); + if (hasError) throw error; } function err(e) { diff --git a/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/async-dispose-throws-synchronously.js b/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/async-dispose-throws-synchronously.js index a595c0cf0d2e..07b1bfcb3de0 100644 --- a/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/async-dispose-throws-synchronously.js +++ b/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/async-dispose-throws-synchronously.js @@ -2,18 +2,21 @@ return async function () { let disposed = false; let beforeEnd; - const err = {}; + const err1 = {}; + const err2 = {}; let thrown; try { await using x = { [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() { - throw err; + throw err1; } }; + throw err2; } catch (e) { thrown = e; } - expect(thrown).toBe(err); + expect(thrown.suppressed).toBe(err1); + expect(thrown.error).toBe(err2); }(); \ No newline at end of file diff --git a/packages/babel-runtime-corejs3/helpers/dispose.js b/packages/babel-runtime-corejs3/helpers/dispose.js index 0a3b9c579d85..c00104745530 100644 --- a/packages/babel-runtime-corejs3/helpers/dispose.js +++ b/packages/babel-runtime-corejs3/helpers/dispose.js @@ -14,15 +14,12 @@ function dispose_SuppressedError(suppressed, error) { } function _dispose(stack, error, hasError) { function next() { - if (0 !== stack.length) { - var r = stack.pop(); - if (r.a) return _Promise.resolve(r.d.call(r.v)).then(next, err); - try { - r.d.call(r.v); - } catch (e) { - return err(e); - } - return next(); + for (; stack.length > 0;) try { + var r = stack.pop(), + p = r.d.call(r.v); + if (r.a) return _Promise.resolve(p).then(next, err); + } catch (e) { + return err(e); } if (hasError) throw error; } diff --git a/packages/babel-runtime/helpers/dispose.js b/packages/babel-runtime/helpers/dispose.js index 862f8b095d90..45ffbfd2f57f 100644 --- a/packages/babel-runtime/helpers/dispose.js +++ b/packages/babel-runtime/helpers/dispose.js @@ -11,15 +11,12 @@ function dispose_SuppressedError(suppressed, error) { } function _dispose(stack, error, hasError) { function next() { - if (0 !== stack.length) { - var r = stack.pop(); - if (r.a) return Promise.resolve(r.d.call(r.v)).then(next, err); - try { - r.d.call(r.v); - } catch (e) { - return err(e); - } - return next(); + for (; stack.length > 0;) try { + var r = stack.pop(), + p = r.d.call(r.v); + if (r.a) return Promise.resolve(p).then(next, err); + } catch (e) { + return err(e); } if (hasError) throw error; }