- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Thu, 13 Mar 2014 14:45:27 -0400
- To: public-webcrypto@w3.org
Richard asked me to comment in this thread. My apologies for the lack
of sane threading/quoting; I wasn't subscribed to the list...
On Tue, Mar 11, 2014 at 3:07 PM, Mark Watson <watsonm@netflix.com> wrote:
> even type mapping to IDL "any" can throw an exception.
I believe this is incorrect. http://heycam.github.io/webidl/#es-any
doesn't mention any cases when it would, and certainly Gecko's
implementation doesn't.
Converting an ES value to an IDL "object" type can in fact throw if the
passed-in value is a primitive, though.
> It does seem that, longer term, it would make sense for WebIDL to
> incorporate Promises explicitly
It already has, in the spec. Browser implementations may not have
caught up yet; this is a recent change.
For example, http://heycam.github.io/webidl/#es-operations explicitly
says that if an exception is thrown at any point during the steps
defined for the function and the return type is a promise type, then the
exception is caught and a promise rejected with that exception is returned.
So in your spec you should be able to just write:
typedef (object or DOMString) AlgorithmIdentifier;
...
Promise<any> encrypt(AlgorithmIdentifier algorithm,
Key key,
CryptoOperationData data);
and calling encrypt would never throw per current WebIDL spec (modulo
things like out of memory exceptions, naturally; you can't exactly
return a promise in that situation). You do NOT have to explicitly do
anything with "key" and "data" as the spec tries to do right now; they
will be converted to the relevant WebIDL types before the method
returns, but any resulting errors will be reported async via the
returned promise that wraps the thrown exception.
What you _will_ have to do by hand, as things stand, is to explicitly
call out when, if an object is passed, it is converted to the various
WebIDL dictionary types the specification uses. Since conversion to a
WebIDL dictionary type can have side-effects, its ordering with other
things needs to be precisely defined to avoid creating racy behavior.
Doing it async is not the way to go, in my opinion; you want to go ahead
and do it before you create the promise and get to the "asynchronously
perform the remaining steps" bit. That is, the "algorithm
normalization" bit will happen synchronously before the method returns,
but any exceptions from it will be reported asynchronously via the
returned Promise.
One way to do this in your spec is probably to have an Algorithm
dictionary type that just has a "name" attribute, to have a bunch of
more specific dictionary types that do _not_ inherit from Algorithm or
contain a "name" attribute, to manually invoke the "convert to an IDL
dictionary type" algorithm from
http://heycam.github.io/webidl/#es-dictionary at the right points, and
then pass (Algorithm, OtherDictionary) pairs to anything that needs the
name in addition to the information from the other dictionary. You
_could_ make the other dictionaries inherit from Algorithm, but then you
have to worry about the getter for the "name" property on the object not
being idempotent and what your spec should do if it returns a different
value the second time around.
Ryan's proposal for synchronously creating a snapshot of the object
passed in seems to me to be more complicated to specify than the above,
for what it's worth, though I welcome him to prove me wrong with a
concrete proposal about how it should work.
> WebIDL could consider having Dictionary IDL types carry with them a
> reference to the original object so that downcasts are possible.
That's true. You have to be careful, because of the side-effects issue,
but it might be possible to do this sort of thing. Please send mail to
public-script-coord? I agree that dictionary inheritance is pretty
weird in WebIDL right now...
Hope that helps,
Boris
Received on Thursday, 13 March 2014 18:45:58 UTC