-
Notifications
You must be signed in to change notification settings - Fork 378
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
The custom element state when constructor thrown #533
Comments
Interesting. So the concrete test case is <script>
let shouldThrow = true;
customElements.define("x-bad", class XBad extends HTMLElement {
constructor() {
super();
if (shouldThrow) {
throw new Error("bad");
shouldThrow = false;
}
}
});
</script>
<x-bad></x-bad> Per the current spec this will try to create an XBad, then fail, but then upon insertion, try to "upgrade" from HTMLUnknownElement to XBad, and succeed. This is especially weird since the "upgrade" goes laterally across the hierarchy (i.e. from HTMLUnknownElement to XBad, instead of from HTMLElement to XBad). One "solution" would be to say that this is an OK edge case that emerges from the semantics, but we should probably clean up the potential for a lateral transition, so make it HTMLElement instead of HTMLUnknownElement. Otherwise, if we want to say that throwing in your constructor means we should never try to upgrade you, then the most straightforward solution I can think of is to add a new custom element state, "unupgradeable", which we set if the constructor fails. Then any future upgrades or try-to-upgrades would bail out if they see this state. We would probably also use this in other cases, such that if upgrading fails once, we should never try it again. What do people think would be better? |
Probably should still try again, as the error may have been due to something missing or not in place at runtime, but could be in a future point in time, in which case upgrading would work ( |
I don't think we should try to update an element in the case it had failed to construct. |
@rniwa so just to make sure I understand, you are in favor of adding an "unupgradeable" state, to ensure that any constructors that fail are never invoked again? |
I agree with @rniwa that we shouldn't run constructor mulitple times on the same element. One more thing we need to take care of, if we were to add a new state, is that whether the new state is defined or not. Semantically, it is not defined. However, the expected most common use case of defined is I mildly prefer it be defined for the reason above, but I'm ok either way. And if we were to make it as defined, we could use uncustomized too. I'm ok either way on this too. |
Hmm. I think it would be better to be not defined. After all, it will not work like a defined element would. It has not yet been upgraded (and never will be). |
This is part of WICG/webcomponents#533. It introduces a new custom element state of "failed", which HTML will use on failed upgrades or failed parser-initiated element creation, to ensure that if a constructor fails, the element will not be upgraded in the future (i.e. the constructor will not be called again for that element).
If creating an element failed the first time due a misbehaving constructor, it was possible that in the future we would try to upgrade the element, running the constructor again. This commit uses the newly-introduced (as of whatwg/dom#282) custom element state of "failed" to prevent upgrading such elements. Fixes WICG/webcomponents#533.
PRs up to fix this at whatwg/dom#282 and whatwg/html#1558. It turned out to be fairly straightforward and fit with existing mechanisms nicely. |
If creating an element failed the first time due a misbehaving constructor, it was possible that in the future we would try to upgrade the element, running the constructor again. This commit uses the newly-introduced (as of whatwg/dom#282) custom element state of "failed" to prevent upgrading such elements. Fixes WICG/webcomponents#533.
This is part of WICG/webcomponents#533. It introduces a new custom element state of "failed", which HTML will use on failed upgrades or failed parser-initiated element creation, to ensure that if a constructor fails, the element will not be upgraded in the future (i.e. the constructor will not be called again for that element). (This also fixes a typo introduced when the DOM Standard got converted to use bikeshed.)
If creating an element failed the first time due a misbehaving constructor, it was possible that in the future we would try to upgrade the element, running the constructor again. This commit uses the newly-introduced (as of whatwg/dom#282) custom element state of "failed" to prevent upgrading such elements. Fixes WICG/webcomponents#533.
It seems to me like preventing the constructor from ever running again is not the best thing to do. What if some error state elsewhere in the app causes the constructor to fail, and then that error state goes away, in which case the element should come alive again the next time it is used. Or, does this explicitly prevent the constructor from running twice on a specific element such that if I removed class SomeElement extends HTMLElement {
constructor() {
if (!someStateInTheApp) {
throw SomeError('...')
}
// ...
}
} Would the best practice for a library that writes a constructor like that be to encourage the failed element to be removed and for the user to try again by adding a new element? |
Yes.
I think the best practice would be not to rely on specific states the app may or may not be in while your constructor is running. Keep your constructor as light as possible (only setting up its own state and tree, for instance) to avoid potential errors. Add initialisation and cleanup routines to callbacks. |
…ructor calls This is part of WICG/webcomponents#533. It introduces a new custom element state of "failed", which HTML will use on failed upgrades or failed parser-initiated element creation, to ensure that if a constructor fails, the element will not be upgraded in the future (i.e. the constructor will not be called again for that element). Also fix a tiny syntax error.
If creating an element failed the first time due a misbehaving constructor, it was possible that in the future we would try to upgrade the element, running the constructor again. This commit uses the newly-introduced (as of whatwg/dom#282) custom element state of "failed" to prevent upgrading such elements. Fixes WICG/webcomponents#533.
The create an element for a token step 7 says when create an element thrown:
Then when this element is inserted, the insert a node tries to upgrade this element.
Shouldn't we prevent to upgrade elements whose constructor thrown?
@domenic @dominiccooney
The text was updated successfully, but these errors were encountered: