Skip to content

Commit e879cb5

Browse files
authored
fix not passing child_ctx for catch block (#5261)
1 parent 76b7196 commit e879cb5

File tree

8 files changed

+180
-2
lines changed

8 files changed

+180
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247))
77
* Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252))
88
* Fix using `<Namespaced.Component/>`s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255))
9+
* Fix using `<svelte:component>` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259))
910

1011
## 3.24.1
1112

src/compiler/compile/render_dom/wrappers/AwaitBlock.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,15 @@ export default class AwaitBlockWrapper extends Wrapper {
231231

232232
const dependencies = this.node.expression.dynamic_dependencies();
233233

234+
let update_child_context;
235+
if (this.then.value && this.catch.value) {
236+
update_child_context = b`#child_ctx[${this.then.value_index}] = #child_ctx[${this.catch.value_index}] = ${info}.resolved;`;
237+
} else if (this.then.value) {
238+
update_child_context = b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`;
239+
} else if (this.catch.value) {
240+
update_child_context = b`#child_ctx[${this.catch.value_index}] = ${info}.resolved;`;
241+
}
242+
234243
if (dependencies.length > 0) {
235244
const condition = x`
236245
${block.renderer.dirty(dependencies)} &&
@@ -247,7 +256,7 @@ export default class AwaitBlockWrapper extends Wrapper {
247256
248257
} else {
249258
const #child_ctx = #ctx.slice();
250-
${this.then.value && b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`}
259+
${update_child_context}
251260
${info}.block.p(#child_ctx, #dirty);
252261
}
253262
`);
@@ -261,7 +270,7 @@ export default class AwaitBlockWrapper extends Wrapper {
261270
block.chunks.update.push(b`
262271
{
263272
const #child_ctx = #ctx.slice();
264-
${this.then.value && b`#child_ctx[${this.then.value_index}] = ${info}.resolved;`}
273+
${update_child_context}
265274
${info}.block.p(#child_ctx, #dirty);
266275
}
267276
`);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
export let count;
3+
export let value;
4+
</script>
5+
6+
<div>count: {count}</div>
7+
<div>value: {value}</div>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
export default {
2+
props: {
3+
thePromise: new Promise((_) => {}),
4+
count: 0,
5+
},
6+
7+
html: `
8+
<div><p>loading...</p></div>
9+
`,
10+
11+
async test({ assert, component, target }) {
12+
await (component.thePromise = Promise.resolve({ value: "success", Component: component.Component }));
13+
14+
assert.htmlEqual(
15+
target.innerHTML,
16+
`
17+
<div>Resolved:
18+
<div>count: 0</div>
19+
<div>value: success</div>
20+
</div>
21+
`
22+
);
23+
24+
component.count = 5;
25+
26+
assert.htmlEqual(
27+
target.innerHTML,
28+
`
29+
<div>Resolved:
30+
<div>count: 5</div>
31+
<div>value: success</div>
32+
</div>
33+
`
34+
);
35+
36+
try {
37+
await (component.thePromise = Promise.reject({ value: "failure", Component: component.Component }));
38+
} catch (error) {
39+
// ignore
40+
}
41+
42+
assert.htmlEqual(
43+
target.innerHTML,
44+
`
45+
<div>Rejected:
46+
<div>count: 5</div>
47+
<div>value: failure</div>
48+
</div>
49+
`
50+
);
51+
52+
component.count = 10;
53+
54+
assert.htmlEqual(
55+
target.innerHTML,
56+
`
57+
<div>Rejected:
58+
<div>count: 10</div>
59+
<div>value: failure</div>
60+
</div>
61+
`
62+
);
63+
},
64+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script>
2+
import Component from './Component.svelte';
3+
export let thePromise;
4+
export let count;
5+
export { Component }
6+
</script>
7+
8+
<div>
9+
{#await thePromise}
10+
<p>loading...</p>
11+
{:then { value: theValue, Component }}
12+
Resolved: <svelte:component this={Component} {count} value={theValue} />
13+
{:catch { value: theError, Component } }
14+
Rejected: <svelte:component this={Component} {count} value={theError} />
15+
{/await}
16+
</div>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let count;
3+
</script>
4+
5+
<div>count: {count}</div>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
export default {
2+
props: {
3+
thePromise: new Promise((_) => {}),
4+
count: 0,
5+
},
6+
7+
html: `
8+
<div><p>loading...</p></div>
9+
`,
10+
11+
async test({ assert, component, target }) {
12+
await (component.thePromise = Promise.resolve(component.Component));
13+
14+
assert.htmlEqual(
15+
target.innerHTML,
16+
`
17+
<div>Resolved:
18+
<div>count: 0</div>
19+
</div>
20+
`
21+
);
22+
23+
component.count = 5;
24+
25+
assert.htmlEqual(
26+
target.innerHTML,
27+
`
28+
<div>Resolved:
29+
<div>count: 5</div>
30+
</div>
31+
`
32+
);
33+
34+
try {
35+
await (component.thePromise = Promise.reject(component.Component));
36+
} catch (error) {
37+
// ignore
38+
}
39+
40+
assert.htmlEqual(
41+
target.innerHTML,
42+
`
43+
<div>Rejected:
44+
<div>count: 5</div>
45+
</div>
46+
`
47+
);
48+
49+
component.count = 10;
50+
51+
assert.htmlEqual(
52+
target.innerHTML,
53+
`
54+
<div>Rejected:
55+
<div>count: 10</div>
56+
</div>
57+
`
58+
);
59+
},
60+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script>
2+
import Component from './Component.svelte';
3+
export let thePromise;
4+
export let count;
5+
export { Component }
6+
</script>
7+
8+
<div>
9+
{#await thePromise}
10+
<p>loading...</p>
11+
{:then theValue}
12+
Resolved: <svelte:component this={theValue} {count} />
13+
{:catch theError}
14+
Rejected: <svelte:component this={theError} {count} />
15+
{/await}
16+
</div>

0 commit comments

Comments
 (0)