From b3d40df333380b4a32ee4695b7083e5b91f66934 Mon Sep 17 00:00:00 2001 From: Gil Pedersen Date: Thu, 24 Oct 2024 18:18:17 +0200 Subject: [PATCH] Fix Error clone() when structuredClone uses bad prototype This can happen in jest which uses node vm to isolate runs --- lib/clone.js | 2 +- test/clone.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/clone.js b/lib/clone.js index dfbbcfd..c05a32a 100755 --- a/lib/clone.js +++ b/lib/clone.js @@ -175,7 +175,7 @@ internals.base = function (obj, baseProto, options) { /* $lab:coverage:off$ */ else if (baseProto === Types.error && internals.structuredCloneExists) { const err = structuredClone(obj); // Needed to copy internal stack state - if (proto !== baseProto) { + if (Object.getPrototypeOf(err) !== proto) { Object.setPrototypeOf(err, proto); // Fix prototype } diff --git a/test/clone.js b/test/clone.js index ae2b001..7035ae7 100755 --- a/test/clone.js +++ b/test/clone.js @@ -886,4 +886,32 @@ describe('clone()', () => { const b = Hoek.clone(a); expect(b.x).to.not.exist(); }); + + it('handles structuredClone not returning proper Error instances', { skip: typeof structuredClone !== 'function' }, () => { + + // This can happen when running in a VM + + const error = new Error('blam'); + + const origStructuredClone = structuredClone; + try { + structuredClone = function (obj) { + + const clone = origStructuredClone.call(this, obj); + if (obj === error) { + Object.setPrototypeOf(clone, Object); + } + + return clone; + }; + + var cloned = Hoek.clone(error); + } + finally { + structuredClone = origStructuredClone; + } + + expect(cloned).to.be.instanceOf(Error); + expect(cloned).to.equal(error); + }); });