summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/structured-clone/errors.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/structured-clone/errors.js')
-rw-r--r--js/src/jit-test/tests/structured-clone/errors.js139
1 files changed, 139 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/structured-clone/errors.js b/js/src/jit-test/tests/structured-clone/errors.js
new file mode 100644
index 0000000000..6e72d46b7c
--- /dev/null
+++ b/js/src/jit-test/tests/structured-clone/errors.js
@@ -0,0 +1,139 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+load(libdir + "asserts.js");
+
+function roundtrip(error) {
+ return deserialize(serialize(error, []));
+}
+
+// Basic
+{
+ let error = new Error("hello world");
+ let cloned = roundtrip(error);
+
+ assertDeepEq(cloned, error);
+ assertEq(cloned.name, "Error");
+ assertEq(cloned.message, "hello world");
+ assertEq(cloned.stack, error.stack);
+}
+
+let constructors = [Error, EvalError, RangeError, ReferenceError,
+ SyntaxError, TypeError, URIError];
+for (let constructor of constructors) {
+ // With message
+ let error = new constructor("hello");
+ let cloned = roundtrip(error);
+ assertDeepEq(cloned, error);
+ assertEq(cloned.hasOwnProperty('message'), true);
+ assertEq(cloned instanceof constructor, true);
+
+ // Without message
+ error = new constructor();
+ cloned = roundtrip(error);
+ assertDeepEq(cloned, error);
+ assertEq(cloned.hasOwnProperty('message'), false);
+ assertEq(cloned instanceof constructor, true);
+
+ // Custom name
+ error = new constructor("hello");
+ error.name = "MyError";
+ cloned = roundtrip(error);
+ assertEq(cloned.name, "Error");
+ assertEq(cloned.message, "hello");
+ assertEq(cloned.stack, error.stack);
+ if (constructor !== Error) {
+ assertEq(cloned instanceof constructor, false);
+ }
+
+ // |cause| property
+ error = new constructor("hello", { cause: new Error("foobar") });
+ cloned = roundtrip(error);
+ assertDeepEq(cloned, error);
+ assertEq(cloned.hasOwnProperty('message'), true);
+ assertEq(cloned instanceof constructor, true);
+ assertEq(cloned.stack, error.stack);
+ assertEq(cloned.stack === undefined, false);
+
+ // |cause| property, manually added after construction.
+ error = new constructor("hello");
+ error.cause = new Error("foobar");
+ assertDeepEq(Object.getOwnPropertyDescriptor(error, "cause"), {
+ value: error.cause,
+ writable: true,
+ enumerable: true,
+ configurable: true,
+ });
+ cloned = roundtrip(error);
+ assertDeepEq(Object.getOwnPropertyDescriptor(cloned, "cause"), {
+ value: cloned.cause,
+ writable: true,
+ enumerable: false, // Non-enumerable in the cloned object!
+ configurable: true,
+ });
+ assertEq(cloned.hasOwnProperty('message'), true);
+ assertEq(cloned instanceof constructor, true);
+ assertEq(cloned.stack, error.stack);
+ assertEq(cloned.stack === undefined, false);
+
+ // Subclassing
+ error = new (class MyError extends constructor {});
+ cloned = roundtrip(error);
+ assertEq(cloned.name, constructor.name);
+ assertEq(cloned.hasOwnProperty('message'), false);
+ assertEq(cloned.stack, error.stack);
+ assertEq(cloned instanceof Error, true);
+
+ // Cross-compartment
+ error = evalcx(`new ${constructor.name}("hello")`);
+ cloned = roundtrip(error);
+ assertEq(cloned.name, constructor.name);
+ assertEq(cloned.message, "hello");
+ assertEq(cloned.stack, error.stack);
+ assertEq(cloned instanceof constructor, true);
+}
+
+// Non-string message
+{
+ let error = new Error("hello world");
+ error.message = 123;
+ let cloned = roundtrip(error);
+ assertEq(cloned.message, "123");
+ assertEq(cloned.hasOwnProperty('message'), true);
+
+ error = new Error();
+ Object.defineProperty(error, 'message', { get: () => {} });
+ cloned = roundtrip(error);
+ assertEq(cloned.message, "");
+ assertEq(cloned.hasOwnProperty('message'), false);
+}
+
+// AggregateError
+{
+ // With message
+ let error = new AggregateError([{a: 1}, {b: 2}], "hello");
+ let cloned = roundtrip(error);
+ assertDeepEq(cloned, error);
+ assertEq(cloned.hasOwnProperty('message'), true);
+ assertEq(cloned instanceof AggregateError, true);
+
+ // Without message
+ error = new AggregateError([{a: 1}, {b: 2}]);
+ cloned = roundtrip(error);
+ assertDeepEq(cloned, error);
+ assertEq(cloned.hasOwnProperty('message'), false);
+ assertEq(cloned instanceof AggregateError, true);
+
+ // Custom name breaks this!
+ error = new AggregateError([{a: 1}, {b: 2}]);
+ error.name = "MyError";
+ cloned = roundtrip(error);
+ assertEq(cloned.name, "Error");
+ assertEq(cloned.message, "");
+ assertEq(cloned.stack, error.stack);
+ assertEq(cloned instanceof AggregateError, false);
+ assertEq(cloned.errors, undefined);
+ assertEq(cloned.hasOwnProperty('errors'), false);
+}