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

Better hydration error messages #3583

Merged
merged 2 commits into from Jan 18, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 21 additions & 6 deletions packages/lit-html/src/experimental-hydrate.ts
Expand Up @@ -131,6 +131,9 @@ export const hydrate = (
// it in the parts cache.
let rootPart: ChildPart | undefined = undefined;

// Used for error messages
let rootPartMarker: Comment | undefined = undefined;

// When we are in-between ChildPart markers, this is the current ChildPart.
// It's needed to be able to set the ChildPart's endNode when we see a
// close marker
Expand All @@ -153,11 +156,16 @@ export const hydrate = (
const markerText = marker.data;
if (markerText.startsWith('lit-part')) {
if (stack.length === 0 && rootPart !== undefined) {
throw new Error('there must be only one root part per container');
throw new Error(
`There must be only one root part per container. ` +
`Found a part marker (${marker}) when we already have a root ` +
`part marker (${rootPartMarker})`
);
}
// Create a new ChildPart and push it onto the stack
currentChildPart = openChildPart(rootValue, marker, stack, options);
rootPart ??= currentChildPart;
rootPartMarker ??= marker;
} else if (markerText.startsWith('lit-node')) {
// Create and hydrate attribute parts into the current ChildPart on the
// stack
Expand All @@ -170,11 +178,18 @@ export const hydrate = (
currentChildPart = closeChildPart(marker, currentChildPart, stack);
}
}
console.assert(
rootPart !== undefined,
'there should be exactly one root part in a render container'
);
// This property needs to remain unminified.
if (rootPart === undefined) {
const elementMessage =
container instanceof ShadowRoot
? `{container.host.localName}'s shadow root`
: container instanceof DocumentFragment
? 'DocumentFragment'
: container.localName;
console.error(
`There should be exactly one root part in a render container, ` +
`but we didn't find any in ${elementMessage}.`
);
} // This property needs to remain unminified.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(container as any)['_$litPart$'] = rootPart;
};
Expand Down