diff --git a/packages/svelte/src/internal/client/dom/blocks/async.js b/packages/svelte/src/internal/client/dom/blocks/async.js index c3828fdb25..b11ad02789 100644 --- a/packages/svelte/src/internal/client/dom/blocks/async.js +++ b/packages/svelte/src/internal/client/dom/blocks/async.js @@ -1,5 +1,6 @@ /** @import { Effect, TemplateNode, Value } from '#client' */ import { DESTROYED } from '#client/constants'; +import { invoke_error_boundary } from '../../error-handling.js'; import { async_derived } from '../../reactivity/deriveds.js'; import { active_effect } from '../../runtime.js'; import { capture, get_pending_boundary } from './boundary.js'; @@ -9,7 +10,7 @@ import { capture, get_pending_boundary } from './boundary.js'; * @param {Array<() => Promise>} expressions * @param {(anchor: TemplateNode, ...deriveds: Value[]) => void} fn */ -export function async(node, expressions, fn) { +export async function async(node, expressions, fn) { // TODO handle hydration var parent = /** @type {Effect} */ (active_effect); @@ -19,12 +20,16 @@ export function async(node, expressions, fn) { boundary.increment(); - Promise.all(expressions.map((fn) => async_derived(fn))).then((result) => { + try { + const result = await Promise.all(expressions.map((fn) => async_derived(fn))); + if ((parent.f & DESTROYED) !== 0) return; restore(); fn(node, ...result); - + } catch (error) { + invoke_error_boundary(error, parent); + } finally { boundary.decrement(); - }); + } } diff --git a/packages/svelte/tests/runtime-runes/samples/async-block-reject-during-init/_config.js b/packages/svelte/tests/runtime-runes/samples/async-block-reject-during-init/_config.js new file mode 100644 index 0000000000..e2718a35d2 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-block-reject-during-init/_config.js @@ -0,0 +1,10 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + assert.htmlEqual(target.innerHTML, 'loading'); + await tick(); + assert.htmlEqual(target.innerHTML, 'nope'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-block-reject-during-init/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-block-reject-during-init/main.svelte new file mode 100644 index 0000000000..412da7268e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-block-reject-during-init/main.svelte @@ -0,0 +1,8 @@ + + {#if await Promise.reject(new Error('nope'))} + hi + {/if} + + {#snippet pending()}loading{/snippet} + {#snippet failed(e)}{e.message}{/snippet} +