1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 21:50:00 -05:00

fix(core): Don't override structured clone error messages from V8 (#13942)

In the implementation of structured serialization in
`Deno.core.serialize`, whenever there is a serialization error, an
exception will be thrown with the message "Failed to serialize
response", even though V8 provides a message to use in such cases.
This change instead throws an exception with the V8-provided message,
if there is one.
This commit is contained in:
Andreu Botella 2022-03-14 19:35:15 +01:00 committed by GitHub
parent b4e42953e1
commit c6bf07ec6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 8 deletions

View file

@ -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",
);
});

View file

@ -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");
}
}

View file

@ -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;
}