[Bug 25048] consider whether an IDL attribute of type Promise<T> should catch exceptions and wrap them up as a rejected Promise like they are for operations

# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

Boris Zbarsky bzbarsky@mit.edu changed:

       What    |Removed                     |Added

             CC|                            |bzbarsky@mit.edu

--- Comment #1 from Boris Zbarsky bzbarsky@mit.edu ---

Are there use cases for attributes of Promise type where this would make sense? They wouldn't be creating a new Promise each time, so it's not like the Promise would represent a operation the attribute getter triggered....

Contact us to advertise here
# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

Domenic Denicola domenic@domenicdenicola.com changed:

       What    |Removed                     |Added

             CC|                            |domenic@domenicdenicola.com

--- Comment #2 from Domenic Denicola domenic@domenicdenicola.com ---

In general, anytime someone is expecting to interface with an asynchronous API, they are expecting asynchronous errors, which are caught via .catch(e => ...). It is very surprising if a synchronous error is thrown. If an API is known to cause both types of errors, you need both .catch(e => ...) and catch(e) { ... }, which is frustrating.

So yes, I think this change would make sense. I'm not sure under what situations it would get triggered---how exception-prone are the operations performed by getters, usually?---but philosophically, it's definitely desirable.

# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #3 from Cameron McCormack cam@mcc.id.au ---

It's not so common for IDL attributes to throw exceptions on getting, but not unheard of.

Hmm, what if you had an IDL attribute of a Promise<T> type that throws when

assigning?

# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #4 from Boris Zbarsky bzbarsky@mit.edu ---

The question is whether there are ever use cases in which a promise attribute is is actually representing asynchronous API.

Or to put this another way: are there any use cases for allowing attributes of Promise type at all?

how exception-prone are the operations performed by getters, usually?

It depends on the getter. The most common practical source of exceptions is if you .call() the getter function on a wrong kind of object.

# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #5 from Domenic Denicola domenic@domenicdenicola.com ---

Or to put this another way: are there any use cases for allowing attributes of Promise type at all?

For sure! See all the usage in 1 or [2]. Or, the recently-proposed loaded/ready promises could easily be attributes, if not for the fact that most of those resources allow you to reload them (e.g. by setting .src again).

The most common practical source of exceptions is if you .call() the getter function on a wrong kind of object.

This should return a rejected promise for the same reason; if you are using a getter representing an asynchronous result, you should expect to be able to do asynchronous error handling.

Hmm, what if you had an IDL attribute of a Promise<T> type that throws when assigning?

Yeah, this is trickier to reason about---mainly because I don't know of a reasonable use case for promise attributes with setters. I assume there'd be coercion behavior, so e.g. for a Promise<long> attribute these would be fine:

foo.bar = 5; foo.bar = Promise.resolve(5);

but these would not:

foo.bar = {}; foo.bar = Promise.resolve(function () { });

I would probably again argue that the result should be foo.bar set to a promise rejected with a TypeError, since people would access the result of the set via

foo.bar.then(processValueRepresentedByBar, couldNotGetValue);

and would be surprised if they had to write

try { foo.bar.then(getValueThatWasSet, couldNotGetValue); } catch (e) { couldNotGetValue(e); }

[2]: rawgithub.com/ClaesNilsson/raw-sockets/gh-pages/index.html#interface-tcpsocket

# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #6 from Cameron McCormack cam@mcc.id.au --- (In reply to Domenic Denicola from comment #5)

Hmm, what if you had an IDL attribute of a Promise<T> type that throws when assigning?

Yeah, this is trickier to reason about---mainly because I don't know of a reasonable use case for promise attributes with setters. I assume there'd be coercion behavior, so e.g. for a Promise<long> attribute these would be fine:

foo.bar = 5; foo.bar = Promise.resolve(5);

but these would not:

foo.bar = {}; foo.bar = Promise.resolve(function () { });

I would probably again argue that the result should be foo.bar set to a promise rejected with a TypeError, since people would access the result of the set via

foo.bar.then(processValueRepresentedByBar, couldNotGetValue);

That's my initial feeling too.

# bugzilla at jessica.w3.org (3 years ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #7 from Boris Zbarsky bzbarsky@mit.edu ---

OK, I guess if you only have one promise representing your state then it makes sense to make it an attribute. But then I'm not sure it makes sense to have that attribute create-and-return promises when called with the wrong this object.

Put another way, I strongly feel like for attribute getters we should preserve the invariant that getter.call(obj) == getter.call(obj) tests true.

So I would argue we should require that getters that return promises not throw normally and allow them to throw if invoked on an object that's the wrong type. In practice, I don't expect anyone to be doing that sort of thing anyway.

As far as setters, if we have no use cases, let's not add complexity and just disallow them. WebIDL already has too many unused (and never will be used!) things that just make it more complex than it should be.

# bugzilla at jessica.w3.org (7 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #8 from Domenic Denicola d@domenic.me --- (In reply to Boris Zbarsky from comment #7)

OK, I guess if you only have one promise representing your state then it makes sense to make it an attribute. But then I'm not sure it makes sense to have that attribute create-and-return promises when called with the wrong this object.

Put another way, I strongly feel like for attribute getters we should preserve the invariant that getter.call(obj) == getter.call(obj) tests true.

I disagree that this invariant applies here. Its synchronous analogue is saying that getter.call(obj), when it fails, should always throw the same error. It's OK to return a different promise in the failure cases.

As far as setters, if we have no use cases, let's not add complexity and just disallow them. WebIDL already has too many unused (and never will be used!) things that just make it more complex than it should be.

Sounds good to me to disallow promise types with setters.

# bugzilla at jessica.w3.org (7 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #9 from Boris Zbarsky bzbarsky@mit.edu ---

Its synchronous analogue is saying that getter.call(obj), when it fails, should always throw the same error.

This argument basically says to me that the basic idea of getters with Promise return values is wacky and we should be using a method instead... But I accept that others disagree on this.

# bugzilla at jessica.w3.org (7 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

Anne annevk@annevk.nl changed:

       What    |Removed                     |Added

             CC|                            |annevk@annevk.nl

--- Comment #10 from Anne annevk@annevk.nl ---

If you cannot depend on === for promises due to the error case, do promises for IDL attributes need to ban [SameObject]?

# bugzilla at jessica.w3.org (7 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

--- Comment #11 from Boris Zbarsky bzbarsky@mit.edu ---

That really depends on the meaning people imbue [SameObject] with. The ambiguity is pretty unfortunate, I agree.

# bugzilla at jessica.w3.org (4 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=25048

Tobie Langel tobie.langel@gmail.com changed:

       What    |Removed                     |Added

         Status|NEW                         |RESOLVED
             CC|                            |tobie.langel@gmail.com
     Resolution|---                         |FIXED

--- Comment #12 from Tobie Langel tobie.langel@gmail.com ---

Fixed in heycam/webidl/commit/4c9c298

Want more features?

Request early access to our private beta of readable email premium.