fix: restore active reaction if then block throws (#14191)

pull/14197/head
Paolo Ricciuti 10 months ago committed by GitHub
parent f1aeaf19e5
commit 44a833fafe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: restore active reaction if then block throws

@ -70,42 +70,44 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {
if (DEV) set_dev_current_component_function(component_function);
}
if (state === PENDING && pending_fn) {
if (pending_effect) resume_effect(pending_effect);
else pending_effect = branch(() => pending_fn(anchor));
}
if (state === THEN && then_fn) {
if (then_effect) resume_effect(then_effect);
else then_effect = branch(() => then_fn(anchor, input_source));
}
try {
if (state === PENDING && pending_fn) {
if (pending_effect) resume_effect(pending_effect);
else pending_effect = branch(() => pending_fn(anchor));
}
if (state === CATCH && catch_fn) {
if (catch_effect) resume_effect(catch_effect);
else catch_effect = branch(() => catch_fn(anchor, error_source));
}
if (state === THEN && then_fn) {
if (then_effect) resume_effect(then_effect);
else then_effect = branch(() => then_fn(anchor, input_source));
}
if (state !== PENDING && pending_effect) {
pause_effect(pending_effect, () => (pending_effect = null));
}
if (state === CATCH && catch_fn) {
if (catch_effect) resume_effect(catch_effect);
else catch_effect = branch(() => catch_fn(anchor, error_source));
}
if (state !== THEN && then_effect) {
pause_effect(then_effect, () => (then_effect = null));
}
if (state !== PENDING && pending_effect) {
pause_effect(pending_effect, () => (pending_effect = null));
}
if (state !== CATCH && catch_effect) {
pause_effect(catch_effect, () => (catch_effect = null));
}
if (state !== THEN && then_effect) {
pause_effect(then_effect, () => (then_effect = null));
}
if (restore) {
if (DEV) set_dev_current_component_function(null);
set_component_context(null);
set_active_reaction(null);
set_active_effect(null);
// without this, the DOM does not update until two ticks after the promise
// resolves, which is unexpected behaviour (and somewhat irksome to test)
flush_sync();
if (state !== CATCH && catch_effect) {
pause_effect(catch_effect, () => (catch_effect = null));
}
} finally {
if (restore) {
if (DEV) set_dev_current_component_function(null);
set_component_context(null);
set_active_reaction(null);
set_active_effect(null);
// without this, the DOM does not update until two ticks after the promise
// resolves, which is unexpected behaviour (and somewhat irksome to test)
flush_sync();
}
}
}

@ -0,0 +1,16 @@
import { ok, test } from '../../test';
import { flushSync } from 'svelte';
export default test({
compileOptions: {
dev: true
},
async test({ target, errors, assert, window }) {
const btn = target.querySelector('button');
ok(btn);
flushSync(() => {
btn.click();
});
assert.deepEqual(errors, []);
}
});

@ -0,0 +1,21 @@
<script>
let count = $state(0);
function listen(node){
function handler(){
count++;
}
node.addEventListener("click", handler);
return {
destroy(){
node.removeEventListener("click", handler);
}
}
}
</script>
<button use:listen></button>
{#await Promise.resolve() then}
{err.or}
{/await}
Loading…
Cancel
Save