From 6c2064b195f7dfa4c8ec61f0b7533cfd2f7f7ab3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 7 Jul 2025 23:20:19 -0400 Subject: [PATCH] only apply error adjustments when error escapes boundaries --- .../src/internal/client/error-handling.js | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/svelte/src/internal/client/error-handling.js b/packages/svelte/src/internal/client/error-handling.js index c9a888658c..8e93923c46 100644 --- a/packages/svelte/src/internal/client/error-handling.js +++ b/packages/svelte/src/internal/client/error-handling.js @@ -7,6 +7,8 @@ import { ERROR_VALUE, BOUNDARY_EFFECT, EFFECT_RAN } from './constants.js'; import { define_property, get_descriptor } from '../shared/utils.js'; import { active_effect, active_reaction } from './runtime.js'; +const adjustments = new WeakMap(); + /** * @param {unknown} error */ @@ -19,14 +21,18 @@ export function handle_error(error) { return error; } - if (DEV && error instanceof Error) { - // adjust_error(error, effect); + if (DEV && error instanceof Error && !adjustments.has(error)) { + adjustments.set(error, get_adjustments(error, effect)); } if ((effect.f & EFFECT_RAN) === 0) { // if the error occurred while creating this subtree, we let it // bubble up until it hits a boundary that can handle it if ((effect.f & BOUNDARY_EFFECT) === 0) { + if (!effect.parent && error instanceof Error) { + apply_adjustments(error); + } + throw error; } @@ -53,6 +59,10 @@ export function invoke_error_boundary(error, effect) { effect = effect.parent; } + if (error instanceof Error) { + apply_adjustments(error); + } + throw error; } @@ -64,7 +74,7 @@ const adjusted_errors = new WeakSet(); * @param {Error} error * @param {Effect} effect */ -function adjust_error(error, effect) { +function get_adjustments(error, effect) { if (adjusted_errors.has(error)) return; adjusted_errors.add(error); @@ -83,17 +93,28 @@ function adjust_error(error, effect) { context = context.p; } - define_property(error, 'message', { - value: error.message + `\n${component_stack}\n` - }); + return { + message: error.message + `\n${component_stack}\n`, + stack: error.stack + ?.split('\n') + .filter((line) => !line.includes('svelte/src/internal')) + .join('\n') + }; +} + +/** + * @param {Error} error + */ +function apply_adjustments(error) { + const adjusted = adjustments.get(error); + + if (adjusted) { + define_property(error, 'message', { + value: adjusted.message + }); - if (error.stack) { - // Filter out internal modules define_property(error, 'stack', { - value: error.stack - .split('\n') - .filter((line) => !line.includes('svelte/src/internal')) - .join('\n') + value: adjusted.stack }); } }