From f3db4dee4d76b19869df05ba7880d638a880edd5 Mon Sep 17 00:00:00 2001 From: XmiliaH Date: Wed, 12 Apr 2023 10:27:04 +0200 Subject: [PATCH] Handle host errors captured in Promises --- lib/setup-sandbox.js | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/setup-sandbox.js b/lib/setup-sandbox.js index 539ce04..71afa52 100644 --- a/lib/setup-sandbox.js +++ b/lib/setup-sandbox.js @@ -439,23 +439,36 @@ global.eval = new LocalProxy(localEval, EvalHandler); * Promise sanitization */ -if (localPromise && !allowAsync) { +if (localPromise) { const PromisePrototype = localPromise.prototype; - overrideWithProxy(PromisePrototype, 'then', PromisePrototype.then, AsyncErrorHandler); - // This seems not to work, and will produce - // UnhandledPromiseRejectionWarning: TypeError: Method Promise.prototype.then called on incompatible receiver [object Object]. - // This is likely caused since the host.Promise.prototype.then cannot use the VM Proxy object. - // Contextify.connect(host.Promise.prototype.then, Promise.prototype.then); + if (!allowAsync) { + + overrideWithProxy(PromisePrototype, 'then', PromisePrototype.then, AsyncErrorHandler); + // This seems not to work, and will produce + // UnhandledPromiseRejectionWarning: TypeError: Method Promise.prototype.then called on incompatible receiver [object Object]. + // This is likely caused since the host.Promise.prototype.then cannot use the VM Proxy object. + // Contextify.connect(host.Promise.prototype.then, Promise.prototype.then); + + } else { + + overrideWithProxy(PromisePrototype, 'then', PromisePrototype.then, { + __proto__: null, + apply(target, thiz, args) { + if (args.length > 1) { + const onRejected = args[1]; + if (typeof onRejected === 'function') { + args[1] = function wrapper(error) { + error = ensureThis(error); + return localReflectApply(onRejected, this, [error]); + }; + } + } + return localReflectApply(target, thiz, args); + } + }); - if (PromisePrototype.finally) { - overrideWithProxy(PromisePrototype, 'finally', PromisePrototype.finally, AsyncErrorHandler); - // Contextify.connect(host.Promise.prototype.finally, Promise.prototype.finally); - } - if (Promise.prototype.catch) { - overrideWithProxy(PromisePrototype, 'catch', PromisePrototype.catch, AsyncErrorHandler); - // Contextify.connect(host.Promise.prototype.catch, Promise.prototype.catch); } }