webmachinelearning / webnn

🧠 Web Neural Network API
https://www.w3.org/TR/webnn/
Other
397 stars 48 forks source link

`MLContext.compute()` explicitly rejects promises where the sub-septs may currently throw #634

Closed huningxin closed 7 months ago

huningxin commented 8 months ago

Regarding to the existing MLContext.compute() algorithm, if input validation steps fail, it returns a rejected promise. However, in the following two steps, transferring an MLNamedArrayBufferViews steps may throw an exception because transfer an ArrayBuffer steps will throw a TypeError if DetachArrayBuffer fails.

  1. Let transferredInputs be the result of transferring MLNamedArrayBufferViews inputs with realm.

  2. Let transferredOutputs be the result of transferring MLNamedArrayBufferViews outputs with realm.

Although the exceptions thrown by step 7 and 8 should be converted to promise rejection automatically, according https://www.w3.org/2001/tag/doc/promises-guide#errors - that says

For Web IDL-based specs, this is taken care of automatically if you declare your operations to return a promise type. Any exceptions thrown by such operations, or by the Web IDL-level type conversions and overload resolution, are automatically converted into rejections.

@inexorabletash suggested

being explicit for subtle things like this is a good idea. Something like "If that throws an exception, return a promise rejected with the exception".

/cc @a-sully

inexorabletash commented 8 months ago

I think the suggested phrasing (biased by my search criteria) would be:

If that threw an exception, then return a new promise rejected with that exception.

And FYI the automagical WebIDL behavior for methods is in https://webidl.spec.whatwg.org/#dfn-create-operation-function -- quoting the relevant steps for method ("operation") op:

And then, if an exception E was thrown:

  1. If op has a return type that is a promise type, then return ! Call(%Promise.reject%, %Promise%, «E»).

... which is basically the same thing if we link "a new promise" and "rejected" to IDL definitions.


Examples for precedent/wording,

https://www.w3.org/TR/FileAPI/

If that threw an exception, return a new promise rejected with that exception.

https://fs.spec.whatwg.org/#create-a-new-filesystemwritablefilestream

If that throws an exception, reject closeResult with that exception and abort these steps.

and some non-promise ones:

https://fetch.spec.whatwg.org/#fetch-controller-abort

If that threw an exception, catch it, and let serializedError be StructuredSerialize(fallbackError).

https://xhr.spec.whatwg.org/#dom-xmlhttprequest-response

If this throws an exception, then set this’s response object to failure and return null. If that threw an exception, then return null.