Skip to content

Commit c268124

Browse files
committed
add async_derived_orphan error
1 parent c78e8e0 commit c268124

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

documentation/docs/98-reference/.generated/client-errors.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->
22

3+
### async_derived_orphan
4+
5+
```
6+
Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
7+
```
8+
9+
In Svelte there are two types of reaction — [`$derived`](https://svelte.dev/docs/svelte/$derived) and [`$effect`](https://svelte.dev/docs/svelte/$effect). Deriveds can be created anywhere, because they run _lazily_ and can be [garbage collected](https://developer.mozilla.org/en-US/docs/Glossary/Garbage_collection) if nothing references them. Effects, by contrast, keep running eagerly whenever their dependencies change, until they are destroyed.
10+
11+
Because of this, effects can only be created inside other effects (or [effect roots](https://svelte.dev/docs/svelte/$effect#$effect.root), such as the one that is created when you first mount a component) so that Svelte knows when to destroy them.
12+
13+
Some sleight of hand occurs when a derived contains an `await` expression: Since waiting until we read `{await getPromise()}` to call `getPromise` would be too late, we use an effect to instead call it proactively, notifying Svelte when the value is available. But since we're using an effect, we can only create asynchronous deriveds inside another effect.
14+
315
### bind_invalid_checkbox_value
416

517
```

packages/svelte/messages/client-errors/errors.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## async_derived_orphan
2+
3+
> Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
4+
5+
In Svelte there are two types of reaction — [`$derived`](https://svelte.dev/docs/svelte/$derived) and [`$effect`](https://svelte.dev/docs/svelte/$effect). Deriveds can be created anywhere, because they run _lazily_ and can be [garbage collected](https://developer.mozilla.org/en-US/docs/Glossary/Garbage_collection) if nothing references them. Effects, by contrast, keep running eagerly whenever their dependencies change, until they are destroyed.
6+
7+
Because of this, effects can only be created inside other effects (or [effect roots](https://svelte.dev/docs/svelte/$effect#$effect.root), such as the one that is created when you first mount a component) so that Svelte knows when to destroy them.
8+
9+
Some sleight of hand occurs when a derived contains an `await` expression: Since waiting until we read `{await getPromise()}` to call `getPromise` would be too late, we use an effect to instead call it proactively, notifying Svelte when the value is available. But since we're using an effect, we can only create asynchronous deriveds inside another effect.
10+
111
## bind_invalid_checkbox_value
212

313
> Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead

packages/svelte/src/internal/client/errors.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,4 +389,20 @@ export function state_unsafe_mutation() {
389389
} else {
390390
throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
391391
}
392+
}
393+
394+
/**
395+
* Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
396+
* @returns {never}
397+
*/
398+
export function async_derived_orphan() {
399+
if (DEV) {
400+
const error = new Error(`async_derived_orphan\nCannot create a \`$derived(...)\` with an \`await\` expression outside of an effect tree\nhttps://svelte.dev/e/async_derived_orphan`);
401+
402+
error.name = 'Svelte error';
403+
404+
throw error;
405+
} else {
406+
throw new Error(`https://svelte.dev/e/async_derived_orphan`);
407+
}
392408
}

packages/svelte/src/internal/client/reactivity/deriveds.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function async_derived(fn, location) {
100100
let parent = /** @type {Effect | null} */ (active_effect);
101101

102102
if (parent === null) {
103-
throw new Error('TODO cannot create unowned async derived');
103+
e.async_derived_orphan();
104104
}
105105

106106
var boundary = /** @type {Boundary} */ (parent.b);

0 commit comments

Comments
 (0)