diff --git a/cli/tests/unit/structured_clone_test.ts b/cli/tests/unit/structured_clone_test.ts index f252761658..fdad0dba76 100644 --- a/cli/tests/unit/structured_clone_test.ts +++ b/cli/tests/unit/structured_clone_test.ts @@ -1,4 +1,4 @@ -import { assert, assertEquals } from "./test_util.ts"; +import { assert, assertEquals, assertThrows } from "./test_util.ts"; // Basic tests for the structured clone algorithm. Mainly tests TypeScript // typings. Actual functionality is tested in WPT. @@ -17,3 +17,14 @@ Deno.test("self.structuredClone", async () => { channelOriginal.port1.close(); portTransferred.close(); }); + +Deno.test("correct DataCloneError message", () => { + assertThrows( + () => { + const sab = new SharedArrayBuffer(1024); + structuredClone(sab, { transfer: [sab] }); + }, + DOMException, + "Value not transferable", + ); +}); diff --git a/core/bindings.rs b/core/bindings.rs index 4e5c68675a..2ab55187d7 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -898,7 +898,7 @@ impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> { scope: &mut v8::HandleScope<'s>, message: v8::Local<'s, v8::String>, ) { - let error = v8::Exception::error(scope, message); + let error = v8::Exception::type_error(scope, message); scope.throw_exception(error); } @@ -1101,15 +1101,25 @@ fn serialize( } } - match value_serializer.write_value(scope.get_current_context(), value) { - Some(true) => { + let must_throw = { + let scope = &mut v8::TryCatch::new(scope); + let ret = value_serializer.write_value(scope.get_current_context(), value); + if scope.has_caught() || scope.has_terminated() { + scope.rethrow(); + false + } else if let Some(true) = ret { let vector = value_serializer.release(); let zbuf: ZeroCopyBuf = vector.into(); rv.set(to_v8(scope, zbuf).unwrap()); + false + } else { + // We throw the TypeError outside of the v8::TryCatch scope. + true } - _ => { - throw_type_error(scope, "Failed to serialize response"); - } + }; + + if must_throw { + throw_type_error(scope, "Failed to serialize response"); } } diff --git a/ext/web/02_structured_clone.js b/ext/web/02_structured_clone.js index 058390cfee..62bb48ebd4 100644 --- a/ext/web/02_structured_clone.js +++ b/ext/web/02_structured_clone.js @@ -77,7 +77,7 @@ return core.deserialize(core.serialize(value)); } catch (e) { if (ObjectPrototypeIsPrototypeOf(TypeErrorPrototype, e)) { - throw new DOMException("Uncloneable value", "DataCloneError"); + throw new DOMException(e.message, "DataCloneError"); } throw e; }