Skip to content

Commit e6b6a68

Browse files
committed
handle fallback error
1 parent 10897ac commit e6b6a68

File tree

3 files changed

+21
-15
lines changed

3 files changed

+21
-15
lines changed

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

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
active_effect,
77
active_reaction,
88
component_context,
9+
handle_error,
910
set_active_effect,
1011
set_active_reaction,
1112
set_component_context
@@ -58,6 +59,7 @@ export function boundary(node, boundary_fn, props) {
5859
block(() => {
5960
var boundary = /** @type {Effect} */ (active_effect);
6061
var hydrate_open = hydrate_node;
62+
var is_rendering_failed = false;
6163

6264
// We re-use the effect's fn property to avoid allocation of an additional field
6365
boundary.fn = (/** @type { Error }} */ error) => {
@@ -72,9 +74,10 @@ export function boundary(node, boundary_fn, props) {
7274
set_hydrate_node(remove_nodes());
7375
}
7476

75-
// If we have nothing to capture the error then rethrow the error
76-
// for another boundary to handle
77-
if (!onerror && !failed_snippet) {
77+
// If we have nothing to capture the error then re-throw the error
78+
// for another boundary to handle, additionaly, if we're rendering
79+
// the fallback and that too fails, then re-throw the error
80+
if ((!onerror && !failed_snippet) || is_rendering_failed) {
7881
throw error;
7982
}
8083

@@ -85,6 +88,7 @@ export function boundary(node, boundary_fn, props) {
8588
}
8689
with_boundary(boundary, () => {
8790
boundary_effect = null;
91+
is_rendering_failed = false;
8892
boundary_effect = branch(() => boundary_fn(anchor));
8993
});
9094
};
@@ -100,13 +104,19 @@ export function boundary(node, boundary_fn, props) {
100104
queue_micro_task(() => {
101105
with_boundary(boundary, () => {
102106
boundary_effect = null;
103-
boundary_effect = branch(() =>
104-
failed_snippet(
105-
anchor,
106-
() => error,
107-
() => reset
108-
)
109-
);
107+
is_rendering_failed = true;
108+
try {
109+
boundary_effect = branch(() => {
110+
failed_snippet(
111+
anchor,
112+
() => error,
113+
() => reset
114+
);
115+
});
116+
} catch (error) {
117+
handle_error(/** @type {Error} */ (error), boundary, boundary.ctx);
118+
}
119+
is_rendering_failed = false;
110120
});
111121
});
112122
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ function should_rethrow_error(effect) {
273273
* @param {Effect} effect
274274
* @param {ComponentContext | null} component_context
275275
*/
276-
function handle_error(error, effect, component_context) {
276+
export function handle_error(error, effect, component_context) {
277277
if (handled_errors.has(error)) {
278278
if (should_rethrow_error(effect)) {
279279
throw error;

packages/svelte/tests/runtime-runes/samples/error-boundary-14/main.svelte

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
<script>
22
import Child from "./Child.svelte";
3-
4-
function throw_error() {
5-
throw new Error('test')
6-
}
73
</script>
84

95
<svelte:boundary onerror={(e) => console.log('error caught')}>

0 commit comments

Comments
 (0)