From 5c0a4a02a5f4429a2687d9d4c627a4638b332d88 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 25 Jun 2025 16:51:40 -0400 Subject: [PATCH] for unowned deriveds, throw errors lazily --- .../svelte/src/internal/client/error-handling.js | 14 ++++++++++---- packages/svelte/src/internal/client/runtime.js | 6 +++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/svelte/src/internal/client/error-handling.js b/packages/svelte/src/internal/client/error-handling.js index 594ef72d25..b88f99041b 100644 --- a/packages/svelte/src/internal/client/error-handling.js +++ b/packages/svelte/src/internal/client/error-handling.js @@ -1,17 +1,23 @@ -/** @import { Effect } from '#client' */ +/** @import { Derived, Effect } from '#client' */ /** @import { Boundary } from './dom/blocks/boundary.js' */ import { DEV } from 'esm-env'; import { FILENAME } from '../../constants.js'; import { is_firefox } from './dom/operations.js'; -import { BOUNDARY_EFFECT, EFFECT_RAN } from './constants.js'; +import { ASYNC_ERROR, BOUNDARY_EFFECT, EFFECT_RAN } from './constants.js'; import { define_property, get_descriptor } from '../shared/utils.js'; -import { active_effect } from './runtime.js'; +import { active_effect, active_reaction } from './runtime.js'; /** * @param {unknown} error */ export function handle_error(error) { - var effect = /** @type {Effect} */ (active_effect); + var effect = active_effect; + + // for unowned deriveds, don't throw until we read the value + if (effect === null) { + /** @type {Derived} */ (active_reaction).f |= ASYNC_ERROR; + return error; + } if (DEV && error instanceof Error) { // adjust_error(error, effect); diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index ae3cc36c34..b1a59de3d6 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -369,9 +369,13 @@ export function update_reaction(reaction) { } } + if ((reaction.f & ASYNC_ERROR) !== 0) { + reaction.f ^= ASYNC_ERROR; + } + return result; } catch (error) { - handle_error(error); + return handle_error(error); } finally { reaction.f ^= REACTION_IS_UPDATING; new_deps = previous_deps;