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

fix(wire-service): add lifecycle hook guards #1092

Merged
merged 2 commits into from
Mar 5, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/@lwc/wire-service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ const wireService = {

connected: (cmp: LightningElement, data: object, def: ElementDef, context: Context) => {
let listeners: NoArgumentListener[];
if (process.env.NODE_ENV !== 'production') {
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't need this check because wiring -> connected transition is sync so it's not possible for this invariant to be violated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can reproduce this in a test if I register the wire adapter after calling createElement and before pushing to the DOM.

Copy link
Contributor

Choose a reason for hiding this comment

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

also, keep in mind that the error boundary protocol allows a sync removal of the elements when the error occur, which means that if a child element throws during construction, the parent shadow will be cleaned up before the connect is invoked all together.

Copy link
Contributor

Choose a reason for hiding this comment

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

If a child element throws during construction, is the wiring hook called for that component? I assume connect and disconnect are not called at all.

the parent shadow will be cleaned up before the connect is invoked all together.

What does cleaned up entail?

Copy link
Contributor

Choose a reason for hiding this comment

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

cleaned up means that the offender VM/CustomElement will get its shadow root cleaned (empty of any element due to a broken state).

throws could occur at many levels, including constructor of the parent, constructor of a child, connected of parent, render of parent, connected of child, render of child, renderedCallback of child, renderedCallback of parent. Plus, the wiring in the middle, which we don't protect today (eventually will). The consequence of a failure will depend on when and where it happens though.

assert.isTrue(!def.wire || context[CONTEXT_ID], 'wire service was not initialized prior to component creation: "connected" service hook invoked without necessary context');
}
if (!def.wire || !(listeners = context[CONTEXT_ID][CONTEXT_CONNECTED])) {
return;
}
Expand All @@ -118,6 +121,9 @@ const wireService = {

disconnected: (cmp: LightningElement, data: object, def: ElementDef, context: Context) => {
let listeners: NoArgumentListener[];
if (process.env.NODE_ENV !== 'production') {
assert.isTrue(!def.wire || context[CONTEXT_ID], 'wire service was not initialized prior to component creation: "disconnected" service hook invoked without necessary context');
}
if (!def.wire || !(listeners = context[CONTEXT_ID][CONTEXT_DISCONNECTED])) {
return;
}
Expand Down