Skip to content

Commit 8e569b0

Browse files
authored
Merge pull request #8976 from QwikDev/fix-updates-after-error
fix: keep sibling updates running after uncaught render errors
2 parents ae74a2c + 1ecc815 commit 8e569b0

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

.changeset/tidy-errors-continue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: keep sibling updates running after uncaught render errors

packages/qwik/src/core/client/dom-container.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
285285
if (!__EXPERIMENTAL__.errorBoundary) {
286286
const errorStore = host && this.resolveContext(host, ERROR_CONTEXT);
287287
if (!errorStore) {
288-
throw err;
288+
logErrorAndThrowAsync(err);
289+
return;
289290
}
290291
errorStore.error = err;
291292
return;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { component$, useSignal, type Signal } from '@qwik.dev/core';
2+
import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing';
3+
import { describe, expect, it } from 'vitest';
4+
5+
describe.each([
6+
{ render: ssrRenderToDom }, //
7+
{ render: domRender }, //
8+
])('$render.name: error handling', ({ render }) => {
9+
it('keeps updating a sibling after an uncaught client render error', async () => {
10+
const Crasher = component$(() => {
11+
throw new Error('boom');
12+
});
13+
14+
const Counter = component$<{ count: Signal<number> }>(({ count }) => (
15+
<button onClick$={() => count.value++}>{count.value}</button>
16+
));
17+
18+
const App = component$(() => {
19+
const count = useSignal(0);
20+
return (
21+
<>
22+
<Counter count={count} />
23+
{count.value === 1 && <Crasher />}
24+
</>
25+
);
26+
});
27+
28+
const { container } = await render(<App />);
29+
const button = container.element.querySelector('button')!;
30+
31+
expect(button.textContent).toBe('0');
32+
await trigger(container.element, button, 'click', {}, { waitForIdle: false });
33+
await trigger(container.element, button, 'click', {}, { waitForIdle: false });
34+
expect(button.textContent).toBe('2');
35+
});
36+
});

0 commit comments

Comments
 (0)