fix: ensure `<svelte:boundary>` properly removes error content in production mode (#15793)

* fix: ensure <svelte:boundary> properly removes error content in production mode

* add changeset
pull/15800/head
zeroberry 5 months ago committed by GitHub
parent 3d80884029
commit b2d5787a09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure <svelte:boundary> properly removes error content in production mode

@ -291,31 +291,21 @@ export function handle_error(error, effect, previous_effect, component_context)
is_throwing_error = true; is_throwing_error = true;
} }
if ( if (DEV && component_context !== null && error instanceof Error && !handled_errors.has(error)) {
!DEV || handled_errors.add(error);
component_context === null ||
!(error instanceof Error) ||
handled_errors.has(error)
) {
propagate_error(error, effect);
return;
}
handled_errors.add(error);
const component_stack = []; const component_stack = [];
const effect_name = effect.fn?.name; const effect_name = effect.fn?.name;
if (effect_name) { if (effect_name) {
component_stack.push(effect_name); component_stack.push(effect_name);
} }
/** @type {ComponentContext | null} */ /** @type {ComponentContext | null} */
let current_context = component_context; let current_context = component_context;
while (current_context !== null) { while (current_context !== null) {
if (DEV) {
/** @type {string} */ /** @type {string} */
var filename = current_context.function?.[FILENAME]; var filename = current_context.function?.[FILENAME];
@ -323,35 +313,36 @@ export function handle_error(error, effect, previous_effect, component_context)
const file = filename.split('/').pop(); const file = filename.split('/').pop();
component_stack.push(file); component_stack.push(file);
} }
current_context = current_context.p;
} }
current_context = current_context.p; const indent = is_firefox ? ' ' : '\t';
} define_property(error, 'message', {
value:
error.message + `\n${component_stack.map((name) => `\n${indent}in ${name}`).join('')}\n`
});
define_property(error, 'component_stack', {
value: component_stack
});
const indent = is_firefox ? ' ' : '\t'; const stack = error.stack;
define_property(error, 'message', {
value: error.message + `\n${component_stack.map((name) => `\n${indent}in ${name}`).join('')}\n` // Filter out internal files from callstack
}); if (stack) {
define_property(error, 'component_stack', { const lines = stack.split('\n');
value: component_stack const new_lines = [];
}); for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const stack = error.stack; if (line.includes('svelte/src/internal')) {
continue;
// Filter out internal files from callstack }
if (stack) { new_lines.push(line);
const lines = stack.split('\n');
const new_lines = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.includes('svelte/src/internal')) {
continue;
} }
new_lines.push(line); define_property(error, 'stack', {
value: new_lines.join('\n')
});
} }
define_property(error, 'stack', {
value: new_lines.join('\n')
});
} }
propagate_error(error, effect); propagate_error(error, effect);

@ -0,0 +1,11 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
test({ assert, target }) {
flushSync();
assert.htmlEqual(target.innerHTML, '<p>error occurred</p>');
}
});

@ -0,0 +1,15 @@
<script>
import Child from "./Child.svelte"
</script>
<svelte:boundary>
<p>This should be removed</p>
{#if true}
<Child />
{/if}
{#snippet failed()}
<p>error occurred</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save