Skip to content

Commit 10897ac

Browse files
committed
fix issue with rethrowing
1 parent 11b2ecd commit 10897ac

File tree

7 files changed

+61
-5
lines changed

7 files changed

+61
-5
lines changed

packages/svelte/src/internal/client/dom/blocks/boundary.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ import {
1010
set_active_reaction,
1111
set_component_context
1212
} from '../../runtime.js';
13-
import { hydrate_next, hydrate_node, hydrating } from '../hydration.js';
13+
import {
14+
hydrate_next,
15+
hydrate_node,
16+
hydrating,
17+
next,
18+
remove_nodes,
19+
set_hydrate_node
20+
} from '../hydration.js';
1421
import { queue_micro_task } from '../task.js';
1522

1623
/**
@@ -50,6 +57,7 @@ export function boundary(node, boundary_fn, props) {
5057

5158
block(() => {
5259
var boundary = /** @type {Effect} */ (active_effect);
60+
var hydrate_open = hydrate_node;
5361

5462
// We re-use the effect's fn property to avoid allocation of an additional field
5563
boundary.fn = (/** @type { Error }} */ error) => {
@@ -58,6 +66,10 @@ export function boundary(node, boundary_fn, props) {
5866

5967
if (boundary_effect) {
6068
destroy_effect(boundary_effect);
69+
} else if (hydrating) {
70+
set_hydrate_node(hydrate_open);
71+
next();
72+
set_hydrate_node(remove_nodes());
6173
}
6274

6375
// If we have nothing to capture the error then rethrow the error

packages/svelte/src/internal/client/runtime.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,19 +258,29 @@ function propagate_error(error, effect) {
258258
throw error;
259259
}
260260

261+
/**
262+
* @param {Effect} effect
263+
*/
264+
function should_rethrow_error(effect) {
265+
return (
266+
(effect.f & DESTROYED) === 0 &&
267+
(effect.parent === null || (effect.parent.f & BOUNDARY_EFFECT) === 0)
268+
);
269+
}
270+
261271
/**
262272
* @param {Error} error
263273
* @param {Effect} effect
264274
* @param {ComponentContext | null} component_context
265275
*/
266276
function handle_error(error, effect, component_context) {
267277
if (handled_errors.has(error)) {
268-
// If the parent is not an error boundary then re-throw the error
269-
if (effect.parent === null || (effect.parent.f & BOUNDARY_EFFECT) === 0) {
278+
if (should_rethrow_error(effect)) {
270279
throw error;
271280
}
272281
return;
273282
}
283+
274284
handled_errors.add(error);
275285

276286
if (!DEV || component_context === null) {
@@ -327,6 +337,9 @@ function handle_error(error, effect, component_context) {
327337
}
328338

329339
propagate_error(error, effect);
340+
if (should_rethrow_error(effect)) {
341+
throw error;
342+
}
330343
}
331344

332345
/**

packages/svelte/tests/runtime-runes/samples/error-boundary-12/_config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { flushSync } from 'svelte';
22
import { test } from '../../test';
33

44
export default test({
5-
test({ assert, target, logs }) {
5+
test({ assert, target }) {
66
const btn = target.querySelector('button');
77

88
btn?.click();

packages/svelte/tests/runtime-runes/samples/error-boundary-13/_config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { flushSync } from 'svelte';
22
import { test } from '../../test';
33

44
export default test({
5-
test({ assert, target, logs }) {
5+
test({ assert, target }) {
66
const btn = target.querySelector('button');
77

88
btn?.click();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
function throw_error() {
3+
throw new Error('throw_error');
4+
}
5+
</script>
6+
7+
{throw_error()}
8+
9+
<div>Foo</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
mode: ['client'],
5+
6+
test({ assert, logs }) {
7+
assert.deepEqual(logs, ['error caught']);
8+
}
9+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
import Child from "./Child.svelte";
3+
4+
function throw_error() {
5+
throw new Error('test')
6+
}
7+
</script>
8+
9+
<svelte:boundary onerror={(e) => console.log('error caught')}>
10+
<Child />
11+
</svelte:boundary>
12+
13+

0 commit comments

Comments
 (0)