import { recordEffect } from './apiReactivity'
import { getCurrentInstance } from './component'
import {
- UserExecutionContexts,
+ ErrorTypes,
callWithErrorHandling,
callWithAsyncErrorHandling
} from './errorHandling'
s =>
isRef(s)
? s.value
- : callWithErrorHandling(
- s,
- instance,
- UserExecutionContexts.WATCH_GETTER
- )
+ : callWithErrorHandling(s, instance, ErrorTypes.WATCH_GETTER)
)
} else if (isRef(source)) {
getter = () => source.value
} else if (cb) {
// getter with cb
getter = () =>
- callWithErrorHandling(
- source,
- instance,
- UserExecutionContexts.WATCH_GETTER
- )
+ callWithErrorHandling(source, instance, ErrorTypes.WATCH_GETTER)
} else {
// no cb -> simple effect
getter = () => {
return callWithErrorHandling(
source,
instance,
- UserExecutionContexts.WATCH_CALLBACK,
+ ErrorTypes.WATCH_CALLBACK,
[registerCleanup]
)
}
const registerCleanup: CleanupRegistrator = (fn: () => void) => {
// TODO wrap the cleanup fn for error handling
cleanup = runner.onStop = () => {
- callWithErrorHandling(fn, instance, UserExecutionContexts.WATCH_CLEANUP)
+ callWithErrorHandling(fn, instance, ErrorTypes.WATCH_CLEANUP)
}
}
if (cleanup) {
cleanup()
}
- callWithAsyncErrorHandling(
- cb,
- instance,
- UserExecutionContexts.WATCH_CALLBACK,
- [newValue, oldValue, registerCleanup]
- )
+ callWithAsyncErrorHandling(cb, instance, ErrorTypes.WATCH_CALLBACK, [
+ newValue,
+ oldValue,
+ registerCleanup
+ ])
oldValue = newValue
}
}
import { ShapeFlags } from './shapeFlags'
import { warn } from './warning'
import {
- UserExecutionContexts,
+ ErrorTypes,
handleError,
callWithErrorHandling,
callWithAsyncErrorHandling
callWithAsyncErrorHandling(
handler[i],
instance,
- UserExecutionContexts.COMPONENT_EVENT_HANDLER,
+ ErrorTypes.COMPONENT_EVENT_HANDLER,
args
)
}
callWithAsyncErrorHandling(
handler,
instance,
- UserExecutionContexts.COMPONENT_EVENT_HANDLER,
+ ErrorTypes.COMPONENT_EVENT_HANDLER,
args
)
}
const setupResult = callWithErrorHandling(
setup,
instance,
- UserExecutionContexts.SETUP_FUNCTION,
+ ErrorTypes.SETUP_FUNCTION,
[propsProxy, setupContext]
)
currentInstance = null
)
}
} catch (err) {
- handleError(err, instance, UserExecutionContexts.RENDER_FUNCTION)
+ handleError(err, instance, ErrorTypes.RENDER_FUNCTION)
return createVNode(Empty)
}
}
// contexts where user provided function may be executed, in addition to
// lifecycle hooks.
-export const enum UserExecutionContexts {
+export const enum ErrorTypes {
SETUP_FUNCTION = 1,
RENDER_FUNCTION,
WATCH_GETTER,
[LifecycleHooks.ERROR_CAPTURED]: 'errorCaptured hook',
[LifecycleHooks.RENDER_TRACKED]: 'renderTracked hook',
[LifecycleHooks.RENDER_TRIGGERED]: 'renderTriggered hook',
- [UserExecutionContexts.SETUP_FUNCTION]: 'setup function',
- [UserExecutionContexts.RENDER_FUNCTION]: 'render function',
- [UserExecutionContexts.WATCH_GETTER]: 'watcher getter',
- [UserExecutionContexts.WATCH_CALLBACK]: 'watcher callback',
- [UserExecutionContexts.WATCH_CLEANUP]: 'watcher cleanup function',
- [UserExecutionContexts.NATIVE_EVENT_HANDLER]: 'native event handler',
- [UserExecutionContexts.COMPONENT_EVENT_HANDLER]: 'component event handler',
- [UserExecutionContexts.SCHEDULER]:
+ [ErrorTypes.SETUP_FUNCTION]: 'setup function',
+ [ErrorTypes.RENDER_FUNCTION]: 'render function',
+ [ErrorTypes.WATCH_GETTER]: 'watcher getter',
+ [ErrorTypes.WATCH_CALLBACK]: 'watcher callback',
+ [ErrorTypes.WATCH_CLEANUP]: 'watcher cleanup function',
+ [ErrorTypes.NATIVE_EVENT_HANDLER]: 'native event handler',
+ [ErrorTypes.COMPONENT_EVENT_HANDLER]: 'component event handler',
+ [ErrorTypes.SCHEDULER]:
'scheduler flush. This may be a Vue internals bug. ' +
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue'
}
-type ErrorTypes = LifecycleHooks | UserExecutionContexts
+type AllErrorTypes = LifecycleHooks | ErrorTypes
export function callWithErrorHandling(
fn: Function,
instance: ComponentInstance | null,
- type: ErrorTypes,
+ type: AllErrorTypes,
args?: any[]
) {
let res: any
export function callWithAsyncErrorHandling(
fn: Function,
instance: ComponentInstance | null,
- type: ErrorTypes,
+ type: AllErrorTypes,
args?: any[]
) {
const res = callWithErrorHandling(fn, instance, type, args)
export function handleError(
err: Error,
instance: ComponentInstance | null,
- type: ErrorTypes
+ type: AllErrorTypes
) {
const contextVNode = instance ? instance.vnode : null
let cur: ComponentInstance | null = instance && instance.parent
logError(err, type, contextVNode)
}
-function logError(err: Error, type: ErrorTypes, contextVNode: VNode | null) {
+function logError(err: Error, type: AllErrorTypes, contextVNode: VNode | null) {
if (__DEV__) {
const info = ErrorTypeStrings[type]
if (contextVNode) {
+import { handleError, ErrorTypes } from './errorHandling'
+
const queue: Function[] = []
const postFlushCbs: Function[] = []
const p = Promise.resolve()
return fn ? p.then(fn) : p
}
-type ErrorHandler = (err: Error) => void
-
-export function queueJob(job: () => void, onError?: ErrorHandler) {
+export function queueJob(job: () => void) {
if (queue.indexOf(job) === -1) {
queue.push(job)
- queueFlush(onError)
+ if (!isFlushing) {
+ nextTick(flushJobs)
+ }
}
}
-export function queuePostFlushCb(
- cb: Function | Function[],
- onError?: ErrorHandler
-) {
+export function queuePostFlushCb(cb: Function | Function[]) {
if (Array.isArray(cb)) {
postFlushCbs.push.apply(postFlushCbs, cb)
} else {
postFlushCbs.push(cb)
}
- queueFlush(onError)
-}
-
-function queueFlush(onError?: ErrorHandler) {
if (!isFlushing) {
- const p = nextTick(flushJobs)
- if (onError) p.catch(onError)
+ nextTick(flushJobs)
}
}
}
}
}
- job()
+ try {
+ job()
+ } catch (err) {
+ handleError(err, null, ErrorTypes.SCHEDULER)
+ }
}
flushPostFlushCbs()
isFlushing = false
ComponentInstance,
callWithAsyncErrorHandling
} from '@vue/runtime-core'
-import { UserExecutionContexts } from 'packages/runtime-core/src/errorHandling'
+import { ErrorTypes } from 'packages/runtime-core/src/errorHandling'
interface Invoker extends Function {
value: EventValue
callWithAsyncErrorHandling(
value[i],
instance,
- UserExecutionContexts.NATIVE_EVENT_HANDLER,
+ ErrorTypes.NATIVE_EVENT_HANDLER,
args
)
}
callWithAsyncErrorHandling(
value,
instance,
- UserExecutionContexts.NATIVE_EVENT_HANDLER,
+ ErrorTypes.NATIVE_EVENT_HANDLER,
args
)
}