diff --git a/.changeset/hip-eagles-yawn.md b/.changeset/hip-eagles-yawn.md new file mode 100644 index 000000000000..c987e7c7f2eb --- /dev/null +++ b/.changeset/hip-eagles-yawn.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: remount at any hydration error diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index ff6844453dcc..3a489f9f927b 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -136,20 +136,28 @@ export function hydrate(component, options) { return /** @type {Exports} */ (instance); } catch (error) { - if (error === HYDRATION_ERROR) { - if (options.recover === false) { - e.hydration_failed(); - } - - // If an error occured above, the operations might not yet have been initialised. - init_operations(); - clear_text_content(target); + // re-throw Svelte errors - they are certainly not related to hydration + if ( + error instanceof Error && + error.message.split('\n').some((line) => line.startsWith('https://svelte.dev/e/')) + ) { + throw error; + } + if (error !== HYDRATION_ERROR) { + // eslint-disable-next-line no-console + console.warn('Failed to hydrate: ', error); + } - set_hydrating(false); - return mount(component, options); + if (options.recover === false) { + e.hydration_failed(); } - throw error; + // If an error occured above, the operations might not yet have been initialised. + init_operations(); + clear_text_content(target); + + set_hydrating(false); + return mount(component, options); } finally { set_hydrating(was_hydrating); set_hydrate_node(previous_hydrate_node); diff --git a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/Nested.svelte b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/Nested.svelte new file mode 100644 index 000000000000..70bf63ad9de2 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/Nested.svelte @@ -0,0 +1 @@ +

nested

\ No newline at end of file diff --git a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_config.js b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_config.js new file mode 100644 index 000000000000..457eeb2201d2 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_config.js @@ -0,0 +1,8 @@ +import { test } from '../../test'; + +export default test({ + errors: [ + 'Failed to hydrate: ', + new DOMException("Node can't be inserted in a #text parent.", 'HierarchyRequestError') + ] +}); diff --git a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_expected.html b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_expected.html new file mode 100644 index 000000000000..46f8e8a7ace4 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_expected.html @@ -0,0 +1 @@ +

nested

\ No newline at end of file diff --git a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html new file mode 100644 index 000000000000..90ca4ef4b8c9 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/_override.html @@ -0,0 +1,2 @@ + +

nested

\ No newline at end of file diff --git a/packages/svelte/tests/hydration/samples/whitespace-at-block-start/main.svelte b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/main.svelte new file mode 100644 index 000000000000..f1f962b95848 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/whitespace-at-block-start/main.svelte @@ -0,0 +1,7 @@ + + +
+ +
\ No newline at end of file