diff --git a/packages/runtime-core/__tests__/errorHandling.spec.ts b/packages/runtime-core/__tests__/errorHandling.spec.ts index d995c5fa057..085127677ba 100644 --- a/packages/runtime-core/__tests__/errorHandling.spec.ts +++ b/packages/runtime-core/__tests__/errorHandling.spec.ts @@ -583,5 +583,31 @@ describe('error handling', () => { expect(handler).toHaveBeenCalledTimes(4) }) + // #9574 + test('should pause tracking in error handler', async () => { + const error = new Error('error') + const x = ref(Math.random()) + + const handler = vi.fn(() => { + x.value + x.value = Math.random() + }) + + const app = createApp({ + setup() { + return () => { + throw error + } + }, + }) + + app.config.errorHandler = handler + app.mount(nodeOps.createElement('div')) + + await nextTick() + expect(handler).toHaveBeenCalledWith(error, {}, 'render function') + expect(handler).toHaveBeenCalledTimes(1) + }) + // native event handler handling should be tested in respective renderers }) diff --git a/packages/runtime-core/src/errorHandling.ts b/packages/runtime-core/src/errorHandling.ts index 041eb123938..dda6480385b 100644 --- a/packages/runtime-core/src/errorHandling.ts +++ b/packages/runtime-core/src/errorHandling.ts @@ -1,3 +1,4 @@ +import { pauseTracking, resetTracking } from '@vue/reactivity' import type { VNode } from './vnode' import type { ComponentInternalInstance } from './component' import { popWarningContext, pushWarningContext, warn } from './warning' @@ -127,12 +128,14 @@ export function handleError( // app-level handling const appErrorHandler = instance.appContext.config.errorHandler if (appErrorHandler) { + pauseTracking() callWithErrorHandling( appErrorHandler, null, ErrorCodes.APP_ERROR_HANDLER, [err, exposedInstance, errorInfo], ) + resetTracking() return } }