Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-align DOMException objects with what is implemented #378

Merged
merged 3 commits into from
Jul 2, 2017

Conversation

domenic
Copy link
Member

@domenic domenic commented Jun 28, 2017

This fixes #55. As discussed there, the definition of DOMException does not match any implementations. 137856d exacerbated this, but it was already incorrect (e.g. defining own properties). Instead, implementations seem to implement DOMException as an interface with a small amount of custom bindings. This updates the specification to reflect that.

As part of this, it is no longer a distinct type, but instead an interface type.


Tests: web-platform-tests/wpt#6361


Preview | Diff

This fixes #55. As discussed there, the definition of DOMException does not match any implementations. 137856d exacerbated this, but it was already incorrect (e.g. defining own properties). Instead, implementations seem to implement DOMException as an interface with a small amount of custom bindings. This updates the specification to reflect that.

As part of this, it is no longer a distinct type, but instead an interface type.
@domenic
Copy link
Member Author

domenic commented Jun 28, 2017

There are a few easy fixes we could do that IMO would make DOMException better without much burden:

  • Make DOMException.__proto__ === Error
  • Make the stringification something more like Safari's by including "(DOMException)"

But I'm aligning with the majority for now, after having gotten bitten already in trying to make DOMException nicer in the past.

@bzbarsky
Copy link
Collaborator

Some comments based on comparing to Gecko's IDL:

  1. Gecko has [LenientThis] on the message and name attributes, with a comment about how otherwise doing DOMException.prototype.toString() will throw, because Error.prototype.toString accesses .message and .name on this. Then again, looks like other browsers throw on DOMException.prototype.toString() (or more likely code like alert(obj) when obj happens to be DOMException.prototype) anyway...

  2. In Gecko DOMException does not implement a stringifier; it picks up the default Error.prototype.toString. So if you do String(new DOMException("a", "b")) you get "b: a". Looks like you just changed the stringifier to do that, but I guess I'm saying we don't really need a custom stringifier at all, unless we want to do the Safari thing.

  3. Minor nit: missing space after = for NO_MODIFICATION_ALLOWED_ERR.

  4. Gecko documents some of the error constants as "historical": DOMSTRING_SIZE_ERR, NO_DATA_ALLOWED_ERR, INUSE_ATTRIBUTE_ERR, VALIDATION_ERR, TYPE_MISMATCH_ERR. Not sure what that means in practice.

Thank you for doing this!

@domenic
Copy link
Member Author

domenic commented Jun 28, 2017

@tabatkins can you help with the following Bikeshed error?

�[1;33mLINK ERROR:�[0m Multiple possible 'dfn' local refs for 'stringification behavior'.
Arbitrarily chose the one with type 'dfn' and for ''.
<a data-link-type="dfn" data-lt="stringification behavior">stringification behavior</a>

I think I'm doing everything right:

The <dfn dfn for="DOMException">stringification behavior</dfn> is to return the concatenation of
this {{DOMException}} object's [=DOMException/name=], ": ", and this {{DOMException}} object's
[=DOMException/message=].

@domenic
Copy link
Member Author

domenic commented Jun 28, 2017

Gecko has [LenientThis] on the message and name attributes

I'll be sure to include a test case, but it looks like we can leave that out.

In Gecko DOMException does not implement a stringifier; it picks up the default Error.prototype.toString.

Good idea, let's do that instead. In that case the stringifier will be influenced by shadowing the properties; I'll be sure to test that too.

In that case, @tabatkins, nevermind, no need for Bikeshed help :)

Gecko documents some of the error constants as "historical"

This is probably related to the grayed-out rows in https://heycam.github.io/webidl/#dfn-error-names-table.


* If an implementation gives native <emu-val>Error</emu-val> objects special powers or
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I've sent an email to v8-dev to discuss what we'd need to do in Chromium and there are some questions over how this would interact with https://github.com/tc39/proposal-error-stacks.

@tabatkins
Copy link
Contributor

can you help with the following Bikeshed error?

I'm not getting that error when I run Bikeshed on the file in this commit. Can you confirm that this is indeed the file causing the problem?

@domenic
Copy link
Member Author

domenic commented Jun 29, 2017

The Bikeshed error went away when I removed the stringifier in a subsequent commit, sorry :). All good now.

@domenic
Copy link
Member Author

domenic commented Jun 30, 2017

@bzbarsky would you mind reviewing so we can merge?

Copy link
Collaborator

@bzbarsky bzbarsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, didn't realize you were waiting for me. This looks good.

@domenic domenic merged commit 5c8eb31 into master Jul 2, 2017
@domenic domenic deleted the fix-domexception branch July 2, 2017 18:33
MXEBot pushed a commit to mirror/chromium that referenced this pull request Jul 3, 2017
They were removed from the WebIDL spec in 2014 ("Removed IDL exceptions,
baked in DOMException, and added Error and DOMException as types"):
whatwg/webidl@50e172e

Support for exception interfaces was implemented by treating them like
WebIDL interfaces and setting |is_exception| in IdlException (which
inherited from IdlInterface). Since DOMException was the only exception
interface we had in the tree, we can just turn it into a proper interface,
check for its name when we need to set |is_exception| and remove all the
lexer/parser/bindings scaffolding we had.

V8DOMException.{cpp,h} generated after the new DOMException.idl have been
verified to be identical to their previous version.

There is work upstream to make DOMException a proper interface (see
whatwg/webidl#378). This change can go in regardless
of the upstream pull request upstream takes, as exception interfaces have
been dead and gone for years.

Bug: 617899, 737497
Change-Id: Iea16c7da733180cd61b14471d0758d5dd68158dc
Reviewed-on: https://chromium-review.googlesource.com/558088
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Raphael Kubo da Costa (rakuco) <raphael.kubo.da.costa@intel.com>
Cr-Commit-Position: refs/heads/master@{#483921}
triple-underscore added a commit to triple-underscore/triple-underscore.github.io that referenced this pull request Jul 3, 2017
domenic added a commit to web-platform-tests/wpt that referenced this pull request Jul 6, 2017
* Add tests for ways in which DOMException is unusual

See whatwg/webidl#55. Follows whatwg/webidl#378.
scheib pushed a commit to scheib/chromium that referenced this pull request Jul 12, 2017
Adapt to whatwg/webidl#378 ("Re-align DOMException
objects with what is implemented").

We were reimplementing toString() in DOMException because of WebKit
r29058 ("Acid3 expects ExeceptionCode constants to be defined on
DOMException objects") from almost 10 years ago. A lot has happened since,
and we can (and should) just use the toString() implementation from
ECMAScript's %ErrorProtoype% (which is explicitly mandated to be in
DOMException's inheritance chain by the WebIDL spec).

Contrary to what's originally described in bug 556950, we do throw an
exception when DOMException.prototype.toString() is called directly: the
WebIDL spec now expects it to, and
web-platform-tests/wpt#6361 tests this behavior.

Additionally, we've changed the way DOMException inherits from
%ErrorPrototype%: instead of doing it in V8PerContextData, we now do it in
V8DOMException::installV8DOMExceptionTemplate(), as the former had problems
with (i)frames detached from the DOM and toString() would just call
Object.prototype.toString() instead.

The only user-visible part of the change is that "toString" is no longer
part of DOMException.prototype's own properties; the error message format is
exactly the same in most cases (the exact steps are described in
https://tc39.github.io/ecma262/#sec-error.prototype.tostring).

Finally, part of http/tests/plugins/cross-frame-object-access.html's
output will change from:
    "Error: Uncaught [object DOMException]"
to
    "Error: Uncaught"
This is tricky because it involves PPAPI and its separate process, but
basically the plugin in an iframe is trying to access top.location.href,
Blink is throwing a SecurityError, but the error message is sent truncated
to PPAPI. The message is truncated because V8 is calling its
NoSideEffectsErrorToString() when creating the message, and this one does
not use the message/name accessors we install, leading to an empty message
(it looked slightly better before because we the presence of our own
toString() caused Object::NoSideEffectsToString() to choose a different
albeit still wrong code path). Blink's handling of this is fine, as the
code in V8Initializer takes care of extracting the name and error message
from the DOMException V8 object that threw the exception.

Bug: 556950, 737497
Change-Id: I9d81edca1de903364bb1aca5950c313885c5964a
Reviewed-on: https://chromium-review.googlesource.com/558904
Commit-Queue: Raphael Kubo da Costa (rakuco) <raphael.kubo.da.costa@intel.com>
Reviewed-by: Mike West <mkwst@chromium.org>
Reviewed-by: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#485960}
annevk pushed a commit to web-platform-tests/wpt that referenced this pull request Jul 14, 2017
As of whatwg/webidl#378, both

    new URLSearchParams(DOMException.prototype)
    DOMException.prototype.toString()

are supposed to throw an exception due to brand checks in properties such as
"name" and "message", which meant compliant implementations were always
failing one of the tests here.

Fix it by passing a `DOMException` instead: it has all the constants we need
and passes the required property checks. Also assert that the previous
behavior throws a TypeError.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

DOMException function definition makes no sense
4 participants