fix: recover when an unexpected node replaces a nested boundary comment (#18925)

Fixes #18924


---------

Co-authored-by: nimbly1 <258366730+nimbly1@users.noreply.github.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
pull/18821/merge
nimbly1 14 hours ago committed by GitHub
parent e5169f26c5
commit 5cbdd34374
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: recover when an unexpected node replaces a nested boundary comment during hydration

@ -32,6 +32,7 @@ import {
hydrate_node,
hydrating,
next,
read_hydration_instruction,
skip_nodes,
set_hydrate_node
} from '../hydration.js';
@ -164,16 +165,18 @@ export class Boundary {
this.#effect = block(() => {
if (hydrating) {
const comment = /** @type {Comment} */ (this.#hydrate_open);
const comment_data = read_hydration_instruction(
/** @type {TemplateNode} */ (this.#hydrate_open)
);
hydrate_next();
const server_rendered_pending = comment.data === HYDRATION_START_ELSE;
const server_rendered_failed = comment.data.startsWith(HYDRATION_START_FAILED);
const server_rendered_pending = comment_data === HYDRATION_START_ELSE;
const server_rendered_failed = comment_data.startsWith(HYDRATION_START_FAILED);
if (server_rendered_failed) {
// Server rendered the failed snippet - hydrate it.
// The serialized error is embedded in the comment: <!--[?<json>-->
const serialized_error = JSON.parse(comment.data.slice(HYDRATION_START_FAILED.length));
const serialized_error = JSON.parse(comment_data.slice(HYDRATION_START_FAILED.length));
this.#hydrate_failed_content(serialized_error);
} else if (server_rendered_pending) {
this.#hydrate_pending_content();

@ -0,0 +1,6 @@
import { test } from '../../test';
// https://github.com/sveltejs/svelte/issues/18924
export default test({
expect_hydration_error: true
});

@ -0,0 +1 @@
<!--[--><!--[--><div><span></span><!--[--><p>inner</p><!--]--></div><!--]--><!--]-->

@ -0,0 +1,14 @@
<svelte:boundary>
<div>
<svelte:boundary>
<p>inner</p>
{#snippet failed()}
<p>inner failed</p>
{/snippet}
</svelte:boundary>
</div>
{#snippet failed()}
<p>outer failed</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save