From 997ccefea96820934e0cf53d07f079635fd29922 Mon Sep 17 00:00:00 2001 From: raythurnvoid <53383860+raythurnvoid@users.noreply.github.com> Date: Sun, 15 Jun 2025 17:32:14 +0100 Subject: [PATCH] Add a warning when the misuse of `reset` in an `error:boundary` causes an error to be thrown when flushing the boundary content --- .../.generated/client-warnings.md | 68 +++++++++++++++++++ .../messages/client-warnings/warnings.md | 66 ++++++++++++++++++ .../internal/client/dom/blocks/boundary.js | 9 ++- .../svelte/src/internal/client/warnings.js | 11 +++ 4 files changed, 153 insertions(+), 1 deletion(-) diff --git a/documentation/docs/98-reference/.generated/client-warnings.md b/documentation/docs/98-reference/.generated/client-warnings.md index fe90b0db38..e11d73e819 100644 --- a/documentation/docs/98-reference/.generated/client-warnings.md +++ b/documentation/docs/98-reference/.generated/client-warnings.md @@ -200,6 +200,74 @@ Consider the following code: To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable). +### reset_misuse + +``` +reset() was invoked and the `` template threw during flush. Calling `reset` inside the `onerror` handler while the app state is still broken can cause the fresh template to crash during its first render; the error bypassed the to avoid an infinite loop `error` → `reset` → `error` +``` + +When you call `reset()` Svelte tears down the template inside `` and renders a fresh one. If the same bad state that caused the first error in the first place is still present, that fresh mount crashes immediately. To break a potential `error → reset → error` loop, Svelte lets such render-time errors bubble past the boundary. + +Sometimes this happens because you might have called `reset` before the error was thrown (perhaps in the `onclick` handler of the button that will then trigger the error) or inside the `onerror` handler. + +`reset()` should preferably be called **after** the boundary has entered its error state. A common pattern is to call it from a "Try again" button in the fallback UI. + +If you need to call `reset` inside the `onerror` handler, ensure you fix the broken state first, *then* invoke `reset()`. + +The examples below show do's and don'ts: + +```svelte + + + + + {#if showComponent} + + {/if} + +``` + +```svelte + + { + // Fix the problematic state first + reset(); // This will cause the error to be thrown again and bypass the boundary +}}> + + +``` + +```svelte + + + + + {#snippet failed(error)} + + {/snippet} + +``` + +```svelte + + { + componentState = initialComponentState; // Fix/reset the problematic state first + reset(); // Now the regular template will show without errors +}}> + + +``` + ### select_multiple_invalid_value ``` diff --git a/packages/svelte/messages/client-warnings/warnings.md b/packages/svelte/messages/client-warnings/warnings.md index f1901271d1..e161fe4bd9 100644 --- a/packages/svelte/messages/client-warnings/warnings.md +++ b/packages/svelte/messages/client-warnings/warnings.md @@ -168,6 +168,72 @@ Consider the following code: To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable). +## reset_misuse + +> reset() was invoked and the `` template threw during flush. Calling `reset` inside the `onerror` handler while the app state is still broken can cause the fresh template to crash during its first render; the error bypassed the to avoid an infinite loop `error` → `reset` → `error` + +When you call `reset()` Svelte tears down the template inside `` and renders a fresh one. If the same bad state that caused the first error in the first place is still present, that fresh mount crashes immediately. To break a potential `error → reset → error` loop, Svelte lets such render-time errors bubble past the boundary. + +Sometimes this happens because you might have called `reset` before the error was thrown (perhaps in the `onclick` handler of the button that will then trigger the error) or inside the `onerror` handler. + +`reset()` should preferably be called **after** the boundary has entered its error state. A common pattern is to call it from a "Try again" button in the fallback UI. + +If you need to call `reset` inside the `onerror` handler, ensure you fix the broken state first, *then* invoke `reset()`. + +The examples below show do's and don'ts: + +```svelte + + + + + {#if showComponent} + + {/if} + +``` + +```svelte + + { + // Fix the problematic state first + reset(); // This will cause the error to be thrown again and bypass the boundary +}}> + + +``` + +```svelte + + + + + {#snippet failed(error)} + + {/snippet} + +``` + +```svelte + + { + componentState = initialComponentState; // Fix/reset the problematic state first + reset(); // Now the regular template will show without errors +}}> + + +``` + ## select_multiple_invalid_value > The `value` property of a `` element should be an array, but it received a non-array value. The selection will be kept as is. */