fix: unlink errored and otherwise finished batch (#18264)

This fixes the issue in
https://github.com/sveltejs/svelte/issues/18221#issuecomment-4497918414
where an error can create follup-up invariant errors. The batch errors,
has no chance to run otherwise (no more pending work) and is therefore
"dead". That means we need to unlink it otherwise it's becoming a
"zombie" and hangs around, causing unnecessary and potentially buggy (as
seen in the reproduction) merge/commit work.

I was not able to reduce the reproduction down to a test case that fails
without the fix, but it does make a related error test from #17888 work
more correctly.
pull/18271/head
Simon H 2 months ago committed by GitHub
parent 4656e6895d
commit a6002b587c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: unlink errored and otherwise finished batch

@ -326,6 +326,12 @@ export class Batch {
this.#traverse(root, effects, render_effects);
} catch (e) {
reset_all(root);
// If there's no async work left, this branch is now dead and needs
// to be unlinked to not become a zombie that is never cleaned up.
// See https://github.com/sveltejs/svelte/issues/18221#issuecomment-4497918414
// for a (non-minimal) reproduction that demonstrates a case where this is necessary
// to not get follow-up false-positives via "batch has scheduled roots" invariant errors.
if (!this.#is_deferred()) this.#unlink();
throw e;
}
}

@ -2,7 +2,7 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target, compileOptions }) {
async test({ assert, target }) {
const [toggle, increment] = target.querySelectorAll('button');
flushSync(() => increment.click());
@ -25,8 +25,8 @@ export default test({
`
<button>toggle</button>
<button>count: 2</button>
<p>show: ${compileOptions.experimental?.async ? 'false' : 'true'}</p>
`
<p>show: true</p>
` // show: false would also be fine; this is more about ensuring that things continue to work _somehow_
);
}
});

Loading…
Cancel
Save