fix: more accurate error message when creating orphan effects (#11227)

pull/11244/head
Rich Harris 8 months ago committed by GitHub
parent eac4218402
commit 516cd22686
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: more accurate error message when creating orphan effects

@ -1,5 +1,5 @@
import { snapshot } from '../proxy.js';
import { render_effect } from '../reactivity/effects.js';
import { render_effect, validate_effect } from '../reactivity/effects.js';
import { current_effect, deep_read } from '../runtime.js';
import { array_prototype, get_prototype_of, object_prototype } from '../utils.js';
@ -20,11 +20,7 @@ export let inspect_captured_signals = [];
*/
// eslint-disable-next-line no-console
export function inspect(get_value, inspector = console.log) {
if (!current_effect) {
throw new Error(
'$inspect can only be used inside an effect (e.g. during component initialisation)'
);
}
validate_effect(current_effect, '$inspect');
let initial = true;

@ -31,6 +31,29 @@ import {
import { set } from './sources.js';
import { remove } from '../dom/reconciler.js';
/**
* @param {import('#client').Effect | null} effect
* @param {'$effect' | '$effect.pre' | '$inspect'} rune
* @returns {asserts effect}
*/
export function validate_effect(effect, rune) {
if (effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV
? `: ${rune} can only be used inside an effect (e.g. during component initialisation)`
: '')
);
}
if (is_destroying_effect) {
throw new Error(
'ERR_SVELTE_EFFECT_IN_TEARDOWN' +
(DEV ? `: ${rune} cannot be used inside an effect cleanup function.` : '')
);
}
}
/**
* @param {import("#client").Effect} effect
* @param {import("#client").Reaction} parent_effect
@ -105,18 +128,7 @@ export function effect_active() {
* @param {() => void | (() => void)} fn
*/
export function user_effect(fn) {
if (current_effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV ? ': The Svelte $effect rune can only be used during component initialisation.' : '')
);
}
if (is_destroying_effect) {
throw new Error(
'ERR_SVELTE_EFFECT_IN_TEARDOWN' +
(DEV ? ': The Svelte $effect rune can not be used in the teardown phase of an effect.' : '')
);
}
validate_effect(current_effect, '$effect');
// Non-nested `$effect(...)` in a component should be deferred
// until the component is mounted
@ -140,23 +152,7 @@ export function user_effect(fn) {
* @returns {import('#client').Effect}
*/
export function user_pre_effect(fn) {
if (current_effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
: '')
);
}
if (is_destroying_effect) {
throw new Error(
'ERR_SVELTE_EFFECT_IN_TEARDOWN' +
(DEV
? ': The Svelte $effect.pre rune can not be used in the teardown phase of an effect.'
: '')
);
}
validate_effect(current_effect, '$effect.pre');
return render_effect(fn);
}

Loading…
Cancel
Save