Skip to content

Commit 83b463b

Browse files
committed
fix(runtime-core):#5657
1 parent 245230e commit 83b463b

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

packages/runtime-core/__tests__/vnode.spec.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from '../src/vnode'
1313
import { Data } from '../src/component'
1414
import { ShapeFlags, PatchFlags } from '@vue/shared'
15-
import { h, reactive, isReactive, setBlockTracking, ref } from '../src'
15+
import { h, reactive, isReactive, setBlockTracking, ref, withCtx } from '../src'
1616
import { createApp, nodeOps, serializeInner } from '@vue/runtime-test'
1717
import { setCurrentRenderingInstance } from '../src/componentRenderContext'
1818

@@ -614,6 +614,29 @@ describe('vnode', () => {
614614
]))
615615
expect(vnode.dynamicChildren).toStrictEqual([])
616616
})
617+
// #5657
618+
test('error of slot function execution should not affect block tracking', () => {
619+
const error = new Error('slot execution error')
620+
let caughtError
621+
const slot = withCtx(
622+
() => {
623+
throw error
624+
},
625+
{ type: {}, appContext: {} } as any
626+
)
627+
try {
628+
slot()
629+
} catch (e) {
630+
caughtError = e
631+
}
632+
expect(caughtError).toBe(error)
633+
expect(
634+
`[Vue warn]: Unhandled error during execution of slot function`
635+
).toHaveBeenWarned()
636+
637+
const vnode = (openBlock(), createBlock('div'))
638+
expect(vnode.dynamicChildren).toStrictEqual([])
639+
})
617640
})
618641

619642
describe('transformVNodeArgs', () => {

packages/runtime-core/src/componentRenderContext.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ComponentInternalInstance } from './component'
22
import { devtoolsComponentUpdated } from './devtools'
33
import { setBlockTracking } from './vnode'
4+
import { handleError, ErrorCodes } from './errorHandling'
45

56
/**
67
* mark the current rendering instance for asset resolution (e.g.
@@ -89,10 +90,16 @@ export function withCtx(
8990
setBlockTracking(-1)
9091
}
9192
const prevInstance = setCurrentRenderingInstance(ctx)
92-
const res = fn(...args)
93-
setCurrentRenderingInstance(prevInstance)
94-
if (renderFnWithContext._d) {
95-
setBlockTracking(1)
93+
let res
94+
try {
95+
res = fn(...args)
96+
} catch (e) {
97+
handleError(e, prevInstance, ErrorCodes.SLOT_FUNCTION)
98+
} finally {
99+
setCurrentRenderingInstance(prevInstance)
100+
if (renderFnWithContext._d) {
101+
setBlockTracking(1)
102+
}
96103
}
97104

98105
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {

packages/runtime-core/src/errorHandling.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ export const enum ErrorCodes {
2020
APP_WARN_HANDLER,
2121
FUNCTION_REF,
2222
ASYNC_COMPONENT_LOADER,
23-
SCHEDULER
23+
SCHEDULER,
24+
SLOT_FUNCTION
2425
}
2526

2627
export const ErrorTypeStrings: Record<number | string, string> = {
@@ -54,7 +55,8 @@ export const ErrorTypeStrings: Record<number | string, string> = {
5455
[ErrorCodes.ASYNC_COMPONENT_LOADER]: 'async component loader',
5556
[ErrorCodes.SCHEDULER]:
5657
'scheduler flush. This is likely a Vue internals bug. ' +
57-
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
58+
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core',
59+
[ErrorCodes.SLOT_FUNCTION]: 'slot function'
5860
}
5961

6062
export type ErrorTypes = LifecycleHooks | ErrorCodes

0 commit comments

Comments
 (0)