From afdcc0e81f374691cf87bada6236699e20819106 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 1 Dec 2021 07:00:16 -0800 Subject: [PATCH] errors: make AbortError structured cloneable Refs: https://github.com/nodejs/node/issues/41038 Signed-off-by: James M Snell --- lib/internal/errors.js | 29 +++++++++++++++++++ .../test-errors-cloneabledomexception.js | 22 +++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 4dadb268cea683..1eaa7406d3d65c 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -60,6 +60,12 @@ const { URIError, } = primordials; +const { + makeTransferable, + kClone, + kDeserialize, +} = require('internal/worker/js_transferable'); + const kIsNodeError = Symbol('kIsNodeError'); const isWindows = process.platform === 'win32'; @@ -825,6 +831,29 @@ class AbortError extends Error { super('The operation was aborted'); this.code = 'ABORT_ERR'; this.name = 'AbortError'; + // eslint-disable-next-line no-constructor-return + return makeTransferable(this); + } + + [kClone]() { + const name = this.name; + const message = this.message; + const stack = this.stack; + const code = this.code; + const cause = this.cause; + + return { + data: { name, message, stack, code, cause }, + deserializeInfo: 'internal/errors:AbortError', + }; + } + + [kDeserialize]({ name, message, stack, code, cause }) { + this.name = name; + this.message = message; + this.stack = stack; + this.code = code; + this.cause = cause; } } module.exports = { diff --git a/test/parallel/test-errors-cloneabledomexception.js b/test/parallel/test-errors-cloneabledomexception.js index f8c2f1cf449186..5eedcfa8960ed5 100644 --- a/test/parallel/test-errors-cloneabledomexception.js +++ b/test/parallel/test-errors-cloneabledomexception.js @@ -1,8 +1,14 @@ +// Flags: --expose-internals 'use strict'; const common = require('../common'); -const { strictEqual, ok } = require('assert'); +const { + strictEqual, + notStrictEqual, + ok, +} = require('assert'); +const { AbortError } = require('internal/errors'); const exception = new DOMException('foo', 'AbortError'); strictEqual(exception.name, 'AbortError'); @@ -19,3 +25,17 @@ mc.port1.onmessage = common.mustCall(({ data }) => { mc.port1.close(); }); mc.port2.postMessage(exception); + +// Let's make sure AbortError is cloneable also +const abort = new AbortError(); +const mc2 = new MessageChannel(); +mc2.port1.onmessage = common.mustCall(({ data }) => { + ok(data instanceof AbortError); + ok(data instanceof Error); + notStrictEqual(data, abort); + strictEqual(data.name, abort.name); + strictEqual(data.message, abort.message); + strictEqual(data.code, abort.code); + mc2.port1.close(); +}); +mc2.port2.postMessage(abort);