-
Notifications
You must be signed in to change notification settings - Fork 319
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
Exceptions in update lifecycle are not handled #262
Comments
I think implementing this would requite catching the error via |
If there's performance regression i think it can leave as is and document, so users can catch the errors in specific cases |
I think we need to fix this. Not handling exceptions causes other user-visible problems, like Promises that never resolve. That violates Promise contracts in a pretty bad way. Here's a simple example: import { LitElement, html } from 'lit-element';
class TestElement extends LitElement {
render() {
throw new Error('Test');
return html`<p>Hello!</p>`;
}
}
customElements.define('test-element', TestElement);
(async () => {
let el = new SimpleGreeting();
try {
await el.requestUpdate();
console.log('Resolved');
} catch (e) {
console.log('Rejected', e);
}
})(); |
Copying in a response from me to an internal user who hit something like this issue when throwing in I added this to the next release milestone. I said I think we should fix, but as we discuss the fix it it's possible that instead of rejecting the requestUpdate() / updateComplete Promise, we'll resolve it. Given that we may have multiple, basically uncoordinated, points waiting on an update, I want to consider what they could actually do in response to an exception in rendering. If it's usually nothing, rejecting may unnecessarily complicate using this API - code that definitely wants to know when rendering has completed will need to try/catch and await. I think you should possible reconsider throwing an exception in render(). Aside from propagating an error to waiting code, all it does is abandon the render and preserve the last state, which might not be reflective of anything good at all. It's probably better to decide exactly what you want to display in errors states and just display that. Consider that no native elements throw in rendering, because rendering is basically unobservable as a step to user code. If the goal here is to communicate a failure to other code, I'd like to understand more how the other code will respond. In a synchronous model like React, render exceptions are usually used to just show a nice stack trace over the app in development. We could target something like that instead by firing an error event. |
cc @sorvell |
…updates Fixes #262. Catch exceptions during update and ensure the element marks itself as finished updating. Note, this change also ensures the `updateComplete` promise is rejected if there's an exception during update.
…updates (#607) * Handle exceptions during update so that they do not break subsequent updates Fixes #262. Catch exceptions during update and ensure the element marks itself as finished updating. Note, this change also ensures the `updateComplete` promise is rejected if there's an exception during update. * update tests consistently to use helper to add/remove test elements * Fix lint error * Address review feedback * Address review feedback. * Refines error handling based on review * `shouldUpdate`/`update` are try/caught so that the element state is ok for further updates if an exception is thrown * `firstUpdated`/`updated` are not called if there's an update exception * `performUpdate` is try/caught only to reject the update promise. This is done to handle an override producing an exception. * a private version `_requestUpdate` is called in the property setter to avoid accessing the overridable `updateComplete` promise. * Added additional js doc comments. * Simplify promise check and fix lint errors
Description
If an exception is throw inside updated method, the next property changes do not updates the element
This occurs because, after the error is throw, the check
if (!this._hasRequestedUpdate)
in_invalidate
never evaluates to true (the update Promise is never resolved)Live Demo
https://codepen.io/blikblum/pen/zmEGXL?editors=1001
Steps to Reproduce
Expected Results
It should continue to update on property changes.
Actual Results
It stops to update on property changes
Browsers Affected
Versions
The text was updated successfully, but these errors were encountered: