mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix(core): rethrow exception during structured cloning serialization (#14671)
- Introduced optional callback for Deno.core.serialize API, that returns cloning error if there is one. - Removed try/catch in seralize structured clone function and throw error from callback. - Removed "Object with a getter that throws" assertion from WPT.
This commit is contained in:
parent
3aa6d5d8b0
commit
402b497299
3 changed files with 39 additions and 16 deletions
|
@ -937,6 +937,7 @@ fn decode(
|
||||||
|
|
||||||
struct SerializeDeserialize<'a> {
|
struct SerializeDeserialize<'a> {
|
||||||
host_objects: Option<v8::Local<'a, v8::Array>>,
|
host_objects: Option<v8::Local<'a, v8::Array>>,
|
||||||
|
error_callback: Option<v8::Local<'a, v8::Function>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> {
|
impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> {
|
||||||
|
@ -946,6 +947,15 @@ impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> {
|
||||||
scope: &mut v8::HandleScope<'s>,
|
scope: &mut v8::HandleScope<'s>,
|
||||||
message: v8::Local<'s, v8::String>,
|
message: v8::Local<'s, v8::String>,
|
||||||
) {
|
) {
|
||||||
|
if let Some(cb) = self.error_callback {
|
||||||
|
let scope = &mut v8::TryCatch::new(scope);
|
||||||
|
let undefined = v8::undefined(scope).into();
|
||||||
|
cb.call(scope, undefined, &[message.into()]);
|
||||||
|
if scope.has_caught() || scope.has_terminated() {
|
||||||
|
scope.rethrow();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
let error = v8::Exception::type_error(scope, message);
|
let error = v8::Exception::type_error(scope, message);
|
||||||
scope.throw_exception(error);
|
scope.throw_exception(error);
|
||||||
}
|
}
|
||||||
|
@ -1078,6 +1088,17 @@ fn serialize(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let arg2_to_error_callback = match !args.get(2).is_undefined() {
|
||||||
|
true => match v8::Local::<v8::Function>::try_from(args.get(2)) {
|
||||||
|
Ok(cb) => Some(v8::Local::new(scope, cb)),
|
||||||
|
Err(_) => {
|
||||||
|
throw_type_error(scope, "Invalid argument 3");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false => None,
|
||||||
|
};
|
||||||
|
|
||||||
let options = options.unwrap_or(SerializeDeserializeOptions {
|
let options = options.unwrap_or(SerializeDeserializeOptions {
|
||||||
host_objects: None,
|
host_objects: None,
|
||||||
transfered_array_buffers: None,
|
transfered_array_buffers: None,
|
||||||
|
@ -1105,7 +1126,11 @@ fn serialize(
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialize_deserialize = Box::new(SerializeDeserialize { host_objects });
|
let serialize_deserialize = Box::new(SerializeDeserialize {
|
||||||
|
host_objects,
|
||||||
|
error_callback: arg2_to_error_callback,
|
||||||
|
});
|
||||||
|
|
||||||
let mut value_serializer =
|
let mut value_serializer =
|
||||||
v8::ValueSerializer::new(scope, serialize_deserialize);
|
v8::ValueSerializer::new(scope, serialize_deserialize);
|
||||||
|
|
||||||
|
@ -1227,7 +1252,10 @@ fn deserialize(
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialize_deserialize = Box::new(SerializeDeserialize { host_objects });
|
let serialize_deserialize = Box::new(SerializeDeserialize {
|
||||||
|
host_objects,
|
||||||
|
error_callback: None,
|
||||||
|
});
|
||||||
let mut value_deserializer =
|
let mut value_deserializer =
|
||||||
v8::ValueDeserializer::new(scope, serialize_deserialize, &zero_copy);
|
v8::ValueDeserializer::new(scope, serialize_deserialize, &zero_copy);
|
||||||
|
|
||||||
|
|
|
@ -265,18 +265,15 @@
|
||||||
WeakSetPrototypeAdd(detachedArrayBuffers, arrayBuffer);
|
WeakSetPrototypeAdd(detachedArrayBuffers, arrayBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
let serializedData;
|
const serializedData = core.serialize(data, {
|
||||||
try {
|
hostObjects: ArrayPrototypeFilter(
|
||||||
serializedData = core.serialize(data, {
|
transferables,
|
||||||
hostObjects: ArrayPrototypeFilter(
|
(a) => ObjectPrototypeIsPrototypeOf(MessagePortPrototype, a),
|
||||||
transferables,
|
),
|
||||||
(a) => ObjectPrototypeIsPrototypeOf(MessagePortPrototype, a),
|
transferedArrayBuffers,
|
||||||
),
|
}, (err) => {
|
||||||
transferedArrayBuffers,
|
throw new DOMException(err, "DataCloneError");
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
throw new DOMException(err.message, "DataCloneError");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {globalThis.__bootstrap.messagePort.Transferable[]} */
|
/** @type {globalThis.__bootstrap.messagePort.Transferable[]} */
|
||||||
const serializedTransferables = [];
|
const serializedTransferables = [];
|
||||||
|
|
|
@ -3655,7 +3655,6 @@
|
||||||
"Object Blob object, Blob empty",
|
"Object Blob object, Blob empty",
|
||||||
"Object Blob object, Blob NUL",
|
"Object Blob object, Blob NUL",
|
||||||
"File basic",
|
"File basic",
|
||||||
"Object with a getter that throws",
|
|
||||||
"Serializing a non-serializable platform object fails",
|
"Serializing a non-serializable platform object fails",
|
||||||
"An object whose interface is deleted from the global must still deserialize",
|
"An object whose interface is deleted from the global must still deserialize",
|
||||||
"A subclass instance will deserialize as its closest serializable superclass",
|
"A subclass instance will deserialize as its closest serializable superclass",
|
||||||
|
@ -3682,7 +3681,6 @@
|
||||||
"Object Blob object, Blob empty",
|
"Object Blob object, Blob empty",
|
||||||
"Object Blob object, Blob NUL",
|
"Object Blob object, Blob NUL",
|
||||||
"File basic",
|
"File basic",
|
||||||
"Object with a getter that throws",
|
|
||||||
"Serializing a non-serializable platform object fails",
|
"Serializing a non-serializable platform object fails",
|
||||||
"An object whose interface is deleted from the global must still deserialize",
|
"An object whose interface is deleted from the global must still deserialize",
|
||||||
"A subclass instance will deserialize as its closest serializable superclass",
|
"A subclass instance will deserialize as its closest serializable superclass",
|
||||||
|
|
Loading…
Add table
Reference in a new issue