mirror of https://github.com/sveltejs/svelte
fix: run boundary `onerror` callbacks in a microtask, in case they result in the boundary's destruction (#17561)
* fix: mark parent effect as dirty on error boundary initialization This change ensures that if an error occurs while a parent effect is still initializing, the parent effect is marked as dirty and scheduled to re-run. This addresses scenarios where state updates in the onerror handler do not trigger a re-evaluation of the condition, improving error handling in Svelte components. * chore: add changeset for #17553 * fix: run boundary callbacks in a microtask, in case they result in the boundary's destruction --------- Co-authored-by: frozenflux2 <snowflake30518@gmail.com>pull/17560/head
parent
8c8a22add4
commit
30cea1f9a0
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: run boundary `onerror` callbacks in a microtask, in case they result in the boundary's destruction
|
||||
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
throw new Error('child error');
|
||||
</script>
|
||||
|
||||
<p>Child content</p>
|
||||
@ -0,0 +1,13 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
mode: ['client'],
|
||||
test({ assert, target }) {
|
||||
flushSync();
|
||||
|
||||
// When exception is set by onerror, the {#if !exception} block should hide
|
||||
// and only the {#if exception} block should be visible
|
||||
assert.htmlEqual(target.innerHTML, '<p>caught error: child error</p>');
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,19 @@
|
||||
<script>
|
||||
import Child from './Child.svelte';
|
||||
|
||||
let exception = $state();
|
||||
const onerror = (e) => {
|
||||
exception = e;
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if !exception}
|
||||
<p>condition is {String(!exception)}</p>
|
||||
<svelte:boundary {onerror}>
|
||||
<Child />
|
||||
</svelte:boundary>
|
||||
{/if}
|
||||
|
||||
{#if exception}
|
||||
<p>caught error: {exception.message}</p>
|
||||
{/if}
|
||||
@ -0,0 +1,8 @@
|
||||
<script>
|
||||
// it's important for the test that this isn't an `Error`
|
||||
throw 'child error'
|
||||
</script>
|
||||
|
||||
<p>
|
||||
boom
|
||||
</p>
|
||||
@ -0,0 +1,13 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
mode: ['client'],
|
||||
test({ assert, target }) {
|
||||
flushSync();
|
||||
|
||||
// When exception is set by onerror, the {#if !exception} block should hide
|
||||
// and only the {#if exception} block should be visible
|
||||
assert.htmlEqual(target.innerHTML, '<p>caught error: child error</p>');
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,19 @@
|
||||
<script>
|
||||
import Child from './Child.svelte';
|
||||
|
||||
let exception = $state();
|
||||
const onerror = (e) => {
|
||||
exception = e;
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if !exception}
|
||||
<p>condition is {String(!exception)}</p>
|
||||
<svelte:boundary {onerror}>
|
||||
<Child />
|
||||
</svelte:boundary>
|
||||
{/if}
|
||||
|
||||
{#if exception}
|
||||
<p>caught error: {exception}</p>
|
||||
{/if}
|
||||
Loading…
Reference in new issue