diff --git a/packages/svelte/src/internal/client/async_body.js b/packages/svelte/src/internal/client/async_body.js deleted file mode 100644 index 2336e25ae2..0000000000 --- a/packages/svelte/src/internal/client/async_body.js +++ /dev/null @@ -1,14 +0,0 @@ -import { suspend } from './reactivity/batch.js'; - -/** - * @param {() => Promise} fn - */ -export async function async_body(fn) { - const unsuspend = suspend(); - - try { - await fn(); - } finally { - unsuspend(); - } -} diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 3e030cbd2d..c5b7bb845c 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -1,6 +1,5 @@ export { createAttachmentKey as attachment } from '../../attachments/index.js'; export { FILENAME, HMR, NAMESPACE_SVG } from '../../constants.js'; -export { async_body } from './async_body.js'; export { push, pop, add_svelte_meta } from './context.js'; export { assign, assign_and, assign_or, assign_nullish } from './dev/assign.js'; export { cleanup_styles } from './dev/css.js'; @@ -100,6 +99,7 @@ export { with_script } from './dom/template.js'; export { + async_body, for_await_track_reactivity_loss, save, track_reactivity_loss diff --git a/packages/svelte/src/internal/client/reactivity/async.js b/packages/svelte/src/internal/client/reactivity/async.js index 2b133e5f44..1ea1bbe561 100644 --- a/packages/svelte/src/internal/client/reactivity/async.js +++ b/packages/svelte/src/internal/client/reactivity/async.js @@ -11,7 +11,7 @@ import { set_active_effect, set_active_reaction } from '../runtime.js'; -import { current_batch } from './batch.js'; +import { current_batch, suspend } from './batch.js'; import { async_derived, current_async_effect, @@ -19,6 +19,7 @@ import { derived_safe_equal, set_from_async_derived } from './deriveds.js'; +import { aborted } from './effects.js'; /** * @@ -170,3 +171,21 @@ export function unset_context() { set_component_context(null); if (DEV) set_from_async_derived(null); } + +/** + * @param {() => Promise} fn + */ +export async function async_body(fn) { + const unsuspend = suspend(); + const active = /** @type {Effect} */ (active_effect); + + try { + await fn(); + } catch (error) { + if (!aborted(active)) { + invoke_error_boundary(error, active); + } + } finally { + unsuspend(); + } +} diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/Child.svelte new file mode 100644 index 0000000000..f7ba132ace --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/Child.svelte @@ -0,0 +1,9 @@ + diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/_config.js b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/_config.js new file mode 100644 index 0000000000..298e33e9a2 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/_config.js @@ -0,0 +1,15 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: `

pending

`, + + async test({ assert, target }) { + const [reject] = target.querySelectorAll('button'); + + await tick(); + reject.click(); + await tick(); + assert.htmlEqual(target.innerHTML, '

route: other

'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/main.svelte new file mode 100644 index 0000000000..2f461e96c8 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested-obsolete/main.svelte @@ -0,0 +1,18 @@ + + + + + + {#if route.current === 'home'} + + {:else} +

route: {route.current}

+ {/if} + + {#snippet pending()} +

pending

+ {/snippet} +
diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/Child.svelte index f7ba132ace..11c9ebd653 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/Child.svelte +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/Child.svelte @@ -2,8 +2,6 @@ import { route } from "./main.svelte"; await new Promise(async (_, reject) => { - await Promise.resolve(); - route.current = 'other' route.reject = reject; }); diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/_config.js b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/_config.js index 298e33e9a2..57005b4112 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/_config.js @@ -7,9 +7,8 @@ export default test({ async test({ assert, target }) { const [reject] = target.querySelectorAll('button'); - await tick(); reject.click(); await tick(); - assert.htmlEqual(target.innerHTML, '

route: other

'); + assert.htmlEqual(target.innerHTML, '

failed

'); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/main.svelte index 2f461e96c8..2fdf4c0d2f 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-error-nested/main.svelte @@ -1,18 +1,18 @@ - {#if route.current === 'home'} - - {:else} -

route: {route.current}

- {/if} + {#snippet pending()}

pending

{/snippet} + + {#snippet failed()} +

failed

+ {/snippet}