Skip to content

fix: add a warning when the misuse of reset in an error:boundary causes an error to be thrown when flushing the boundary content #16171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 17, 2025
Merged
Prev Previous commit
Next Next commit
Add tests
  • Loading branch information
raythurnvoid committed Jun 15, 2025
commit 0554c512d9821429c5ccbd029ae49bb36b9cd4c4
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
test({ assert, target, warnings }) {
const btn = target.querySelector('button');

btn?.click();

assert.throws(() => {
flushSync();
}, 'error on template render');

// Check that the warning is being showed to the user
assert.include(warnings[0], 'reset() was invoked');

// boundary content empty; only button remains
assert.htmlEqual(target.innerHTML, `<button>trigger throw</button>`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script>
let must_throw = $state(false);

function throw_error() {
throw new Error("error on template render");
}
</script>

<svelte:boundary onerror={(_, reset) => reset()}>
{must_throw ? throw_error() : 'normal content'}

{#snippet failed()}
<div>err</div>
{/snippet}
</svelte:boundary>

<button onclick={() => must_throw = true}>trigger throw</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
html: `
normal content
<button>toggle</button>
`,

expect_unhandled_rejections: true,

async test({ assert, target, warnings, window }) {
// @ts-expect-error
const __expected_error = (window.__expected_error = { v: false });

window.addEventListener('error', (e) => {
// @ts-expect-error when in hydrate mode we can't access variables in the scope
const __expected_error = window.__expected_error;

if (__expected_error.v) {
assert.include(e.error.message, 'error on template render');
} else {
assert.fail('Error was not expected: ' + e.error.message);
}
e.preventDefault();
});

const btn = target.querySelector('button');

// 1st click — error caught, fallback visible
btn?.click();
flushSync();
assert.htmlEqual(target.innerHTML, `<div>err</div><button>toggle</button>`);

// 2nd click — reset succeeds, normal render
btn?.click();
flushSync();
assert.htmlEqual(
target.innerHTML,
`
normal content
<button>toggle</button>
`
);

// 3rd click — mount-time crash escapes, boundary empty
__expected_error.v = true;
btn?.click();
flushSync();
__expected_error.v = false;

// Check that the warning is being showed to the user
assert.include(warnings[0], 'reset() was invoked');

// boundary content empty; only button remains
assert.htmlEqual(target.innerHTML, `<button>toggle</button>`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script>
let must_throw = $state(false);
let reset = $state(null);

function throw_error() {
throw new Error("error on template render");
}
</script>

<svelte:boundary onerror={console.error}>
<svelte:boundary onerror={(_, fn) => (reset = fn)}>
{must_throw ? throw_error() : 'normal content'}

{#snippet failed()}
<div>err</div>
{/snippet}
</svelte:boundary>
</svelte:boundary>

<button
onclick={() => {
must_throw = !must_throw;
if (reset) reset();
}}>
toggle
</button>
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy