diff --git a/documentation/docs/98-reference/.generated/client-errors.md b/documentation/docs/98-reference/.generated/client-errors.md index 1efc3434ab..c7d6ec8ac9 100644 --- a/documentation/docs/98-reference/.generated/client-errors.md +++ b/documentation/docs/98-reference/.generated/client-errors.md @@ -80,6 +80,12 @@ Effect cannot be created inside a `$derived` value that was not itself created i `%rune%` can only be used inside an effect (e.g. during component initialisation) ``` +### effect_pending_outside_reaction + +``` +`$effect.pending()` can only be called inside an effect or derived +``` + ### effect_update_depth_exceeded ``` diff --git a/packages/svelte/messages/client-errors/errors.md b/packages/svelte/messages/client-errors/errors.md index 0dbe12bda6..2ce25dbd53 100644 --- a/packages/svelte/messages/client-errors/errors.md +++ b/packages/svelte/messages/client-errors/errors.md @@ -54,6 +54,10 @@ See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-long > `%rune%` can only be used inside an effect (e.g. during component initialisation) +## effect_pending_outside_reaction + +> `$effect.pending()` can only be called inside an effect or derived + ## effect_update_depth_exceeded > Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops diff --git a/packages/svelte/scripts/process-messages/templates/client-errors.js b/packages/svelte/scripts/process-messages/templates/client-errors.js index c72e9f9d5e..0fd245be93 100644 --- a/packages/svelte/scripts/process-messages/templates/client-errors.js +++ b/packages/svelte/scripts/process-messages/templates/client-errors.js @@ -1,4 +1,5 @@ import { DEV } from 'esm-env'; +export * from '../shared/errors.js'; /** * MESSAGE diff --git a/packages/svelte/scripts/process-messages/templates/server-errors.js b/packages/svelte/scripts/process-messages/templates/server-errors.js index 6fb7924564..0bbe801abc 100644 --- a/packages/svelte/scripts/process-messages/templates/server-errors.js +++ b/packages/svelte/scripts/process-messages/templates/server-errors.js @@ -1,3 +1,5 @@ +export * from '../shared/errors.js'; + /** * MESSAGE * @param {string} PARAMETER diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index 9212b3d5d4..dfc5ac46fb 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -20,7 +20,7 @@ import { } from '../hydration.js'; import { get_next_sibling } from '../operations.js'; import { queue_micro_task } from '../task.js'; -import * as e from '../../../shared/errors.js'; +import * as e from '../../errors.js'; import { DEV } from 'esm-env'; import { from_async_derived, set_from_async_derived } from '../../reactivity/deriveds.js'; import { Batch } from '../../reactivity/batch.js'; @@ -454,8 +454,11 @@ function exit() { } export function pending() { - // TODO throw helpful error if called outside an effect - const boundary = /** @type {Effect} */ (active_effect).b; + if (active_effect === null) { + e.effect_pending_outside_reaction(); + } + + var boundary = active_effect.b; if (boundary === null) { return 0; // TODO eventually we will need this to be global diff --git a/packages/svelte/src/internal/client/errors.js b/packages/svelte/src/internal/client/errors.js index 232af8429f..a491dc683d 100644 --- a/packages/svelte/src/internal/client/errors.js +++ b/packages/svelte/src/internal/client/errors.js @@ -2,6 +2,8 @@ import { DEV } from 'esm-env'; +export * from '../shared/errors.js'; + /** * Cannot create a `$derived(...)` with an `await` expression outside of an effect tree * @returns {never} @@ -195,6 +197,22 @@ export function effect_orphan(rune) { } } +/** + * `$effect.pending()` can only be called inside an effect or derived + * @returns {never} + */ +export function effect_pending_outside_reaction() { + if (DEV) { + const error = new Error(`effect_pending_outside_reaction\n\`$effect.pending()\` can only be called inside an effect or derived\nhttps://svelte.dev/e/effect_pending_outside_reaction`); + + error.name = 'Svelte error'; + + throw error; + } else { + throw new Error(`https://svelte.dev/e/effect_pending_outside_reaction`); + } +} + /** * Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops * @returns {never} diff --git a/packages/svelte/src/internal/server/errors.js b/packages/svelte/src/internal/server/errors.js index e47530c9aa..458937218f 100644 --- a/packages/svelte/src/internal/server/errors.js +++ b/packages/svelte/src/internal/server/errors.js @@ -1,6 +1,6 @@ /* This file is generated by scripts/process-messages/index.js. Do not edit! */ - +export * from '../shared/errors.js'; /** * `%name%(...)` is not available on the server