diff --git a/.changeset/twelve-cooks-speak.md b/.changeset/twelve-cooks-speak.md new file mode 100644 index 000000000000..d4fcd5c339e9 --- /dev/null +++ b/.changeset/twelve-cooks-speak.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ignore false-positive errors of `$inspect` dependencies diff --git a/packages/svelte/src/internal/client/dev/inspect.js b/packages/svelte/src/internal/client/dev/inspect.js index 75b29ce9b10c..7a8fa0e963f4 100644 --- a/packages/svelte/src/internal/client/dev/inspect.js +++ b/packages/svelte/src/internal/client/dev/inspect.js @@ -20,6 +20,8 @@ export function inspect(get_value, inspector, show_stack = false) { // in an error (an `$inspect(object.property)` will run before the // `{#if object}...{/if}` that contains it) eager_effect(() => { + error = UNINITIALIZED; + try { var value = get_value(); } catch (e) { diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index a5dd94badf82..f374f6a26bf1 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -266,7 +266,24 @@ export function flush_eager_effects() { eager_effects_deferred = false; for (const effect of eager_effects) { - if (is_dirty(effect)) { + // Mark clean inspect-effects as maybe dirty and then check their dirtiness + // instead of just updating the effects - this way we avoid overfiring. + if ((effect.f & CLEAN) !== 0) { + set_signal_status(effect, MAYBE_DIRTY); + } + + let dirty; + + try { + dirty = is_dirty(effect); + } catch { + // Dirty-checking can evaluate derived dependencies and throw in cases where + // parent effects are about to destroy this eager effect. Run the effect so + // its own error handling can deal with transient failures. + dirty = true; + } + + if (dirty) { update_effect(effect); } } diff --git a/packages/svelte/tests/helpers.js b/packages/svelte/tests/helpers.js index d0ec8b6e44de..52bd47dfae7d 100644 --- a/packages/svelte/tests/helpers.js +++ b/packages/svelte/tests/helpers.js @@ -201,7 +201,7 @@ export const async_mode = process.env.SVELTE_NO_ASYNC !== 'true'; * @param {any[]} logs */ export function normalise_inspect_logs(logs) { - /** @type {string[]} */ + /** @type {any[]} */ const normalised = []; for (const log of logs) { diff --git a/packages/svelte/tests/runtime-runes/samples/inspect-derived-if-destroy/List.svelte b/packages/svelte/tests/runtime-runes/samples/inspect-derived-if-destroy/List.svelte new file mode 100644 index 000000000000..c73ac9a99ddb --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/inspect-derived-if-destroy/List.svelte @@ -0,0 +1,11 @@ + + +