diff --git a/packages/svelte/src/internal/client/dom/blocks/async.js b/packages/svelte/src/internal/client/dom/blocks/async.js index 339c05ded7..a68736281d 100644 --- a/packages/svelte/src/internal/client/dom/blocks/async.js +++ b/packages/svelte/src/internal/client/dom/blocks/async.js @@ -1,7 +1,7 @@ /** @import { Effect, TemplateNode, Value } from '#client' */ import { DESTROYED } from '#client/constants'; import { async_derived } from '../../reactivity/deriveds.js'; -import { active_effect } from '../../runtime.js'; +import { active_effect, get } from '../../runtime.js'; import { capture, get_pending_boundary } from './boundary.js'; /** @@ -20,12 +20,15 @@ export async function async(node, expressions, fn) { boundary.update_pending_count(1); try { - const result = await Promise.all(expressions.map((fn) => async_derived(fn))); + const deriveds = await Promise.all(expressions.map((fn) => async_derived(fn))); + + // get deriveds eagerly to avoid creating blocks if they reject + for (const d of deriveds) get(d); if ((parent.f & DESTROYED) !== 0) return; restore(); - fn(node, ...result); + fn(node, ...deriveds); } catch (error) { boundary.error(error); } finally { diff --git a/packages/svelte/tests/runtime-runes/samples/async-error-in-block-expression/_config.js b/packages/svelte/tests/runtime-runes/samples/async-error-in-block-expression/_config.js new file mode 100644 index 0000000000..2679785cff --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-error-in-block-expression/_config.js @@ -0,0 +1,11 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: `loading`, + + async test({ assert, target }) { + await tick(); + assert.htmlEqual(target.innerHTML, 'oops'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-error-in-block-expression/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-error-in-block-expression/main.svelte new file mode 100644 index 0000000000..a49a5c9540 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-error-in-block-expression/main.svelte @@ -0,0 +1,8 @@ + + {#each (await Promise.reject(new Error('oops'))) as x} + hi + {/each} + + {#snippet pending()}loading{/snippet} + {#snippet failed()}oops{/snippet} +