script: Allow to throw a custom exception on structured cloning (#37948)

The structured cloning with transfer list
https://html.spec.whatwg.org/multipage/#structuredserializewithtransfer
throws a "DataCloneError" DOM expection by default if
serialization/transferral
is not possible, but a platform object can throw a custom excepton on
its serialization/transfer steps.

One example is OffscreenCanvas, which can throw
an "InvalidStateError" exception if the context mode is not none on
transfer steps.

https://html.spec.whatwg.org/multipage/#the-offscreencanvas-interface:transfer-steps

Testing: Improvements in the following tests
-
html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable*

Fixes: #37919

Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
Andrei Volykhin 2025-07-09 14:43:09 +03:00 committed by GitHub
parent cae73341b2
commit a5b02047f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 165 additions and 130 deletions

View file

@ -19,7 +19,7 @@ use crate::dom::bindings::codegen::Bindings::MessagePortBinding::{
MessagePortMethods, StructuredSerializeOptions,
};
use crate::dom::bindings::conversions::root_from_object;
use crate::dom::bindings::error::{Error, ErrorResult, ErrorToJsval};
use crate::dom::bindings::error::{Error, ErrorResult, ErrorToJsval, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
@ -256,9 +256,13 @@ impl Transferable for MessagePort {
type Data = MessagePortImpl;
/// <https://html.spec.whatwg.org/multipage/#message-ports:transfer-steps>
fn transfer(&self) -> Result<(MessagePortId, MessagePortImpl), ()> {
fn transfer(&self) -> Fallible<(MessagePortId, MessagePortImpl)> {
// <https://html.spec.whatwg.org/multipage/#structuredserializewithtransfer>
// Step 5.2. If transferable has a [[Detached]] internal slot and
// transferable.[[Detached]] is true, then throw a "DataCloneError"
// DOMException.
if self.detached.get() {
return Err(());
return Err(Error::DataClone(None));
}
self.detached.set(true);