Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | 84x 84x 84x 84x 2727x 2727x 19x 2725x 84x 1543x 1512x 1512x 49x 9x 1512x 31x 31x 62x 31x 84x 52x 52x 51x 51x 51x 51x 47x 47x 32x 32x 26x 21x 25x 25x 23x 23x 3x 3x 3x 3x 2x 3x 3x 2x 3x 2x 1x | import { VNode } from './vnode' import { ComponentInternalInstance, LifecycleHooks } from './component' import { warn, pushWarningContext, popWarningContext } from './warning' import { isPromise, isFunction } from '@vue/shared' // contexts where user provided function may be executed, in addition to // lifecycle hooks. export const enum ErrorCodes { SETUP_FUNCTION, RENDER_FUNCTION, WATCH_GETTER, WATCH_CALLBACK, WATCH_CLEANUP, NATIVE_EVENT_HANDLER, COMPONENT_EVENT_HANDLER, VNODE_HOOK, DIRECTIVE_HOOK, TRANSITION_HOOK, APP_ERROR_HANDLER, APP_WARN_HANDLER, FUNCTION_REF, ASYNC_COMPONENT_LOADER, SCHEDULER } export const ErrorTypeStrings: Record<number | string, string> = { [LifecycleHooks.SERVER_PREFETCH]: 'serverPrefetch hook', [LifecycleHooks.BEFORE_CREATE]: 'beforeCreate hook', [LifecycleHooks.CREATED]: 'created hook', [LifecycleHooks.BEFORE_MOUNT]: 'beforeMount hook', [LifecycleHooks.MOUNTED]: 'mounted hook', [LifecycleHooks.BEFORE_UPDATE]: 'beforeUpdate hook', [LifecycleHooks.UPDATED]: 'updated', [LifecycleHooks.BEFORE_UNMOUNT]: 'beforeUnmount hook', [LifecycleHooks.UNMOUNTED]: 'unmounted hook', [LifecycleHooks.ACTIVATED]: 'activated hook', [LifecycleHooks.DEACTIVATED]: 'deactivated hook', [LifecycleHooks.ERROR_CAPTURED]: 'errorCaptured hook', [LifecycleHooks.RENDER_TRACKED]: 'renderTracked hook', [LifecycleHooks.RENDER_TRIGGERED]: 'renderTriggered hook', [ErrorCodes.SETUP_FUNCTION]: 'setup function', [ErrorCodes.RENDER_FUNCTION]: 'render function', [ErrorCodes.WATCH_GETTER]: 'watcher getter', [ErrorCodes.WATCH_CALLBACK]: 'watcher callback', [ErrorCodes.WATCH_CLEANUP]: 'watcher cleanup function', [ErrorCodes.NATIVE_EVENT_HANDLER]: 'native event handler', [ErrorCodes.COMPONENT_EVENT_HANDLER]: 'component event handler', [ErrorCodes.VNODE_HOOK]: 'vnode hook', [ErrorCodes.DIRECTIVE_HOOK]: 'directive hook', [ErrorCodes.TRANSITION_HOOK]: 'transition hook', [ErrorCodes.APP_ERROR_HANDLER]: 'app errorHandler', [ErrorCodes.APP_WARN_HANDLER]: 'app warnHandler', [ErrorCodes.FUNCTION_REF]: 'ref function', [ErrorCodes.ASYNC_COMPONENT_LOADER]: 'async component loader', [ErrorCodes.SCHEDULER]: 'scheduler flush. This is likely a Vue internals bug. ' + 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core' } export type ErrorTypes = LifecycleHooks | ErrorCodes export function callWithErrorHandling( fn: Function, instance: ComponentInternalInstance | null, type: ErrorTypes, args?: unknown[] ) { let res try { res = args ? fn(...args) : fn() } catch (err) { handleError(err, instance, type) } return res } export function callWithAsyncErrorHandling( fn: Function | Function[], instance: ComponentInternalInstance | null, type: ErrorTypes, args?: unknown[] ): any[] { if (isFunction(fn)) { const res = callWithErrorHandling(fn, instance, type, args) if (res && isPromise(res)) { res.catch(err => { handleError(err, instance, type) }) } return res } const values = [] for (let i = 0; i < fn.length; i++) { values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)) } return values } export function handleError( err: unknown, instance: ComponentInternalInstance | null, type: ErrorTypes, throwInDev = true ) { const contextVNode = instance ? instance.vnode : null if (instance) { let cur = instance.parent // the exposed instance is the render proxy to keep it consistent with 2.x const exposedInstance = instance.proxy // in production the hook receives only the error code const errorInfo = __DEV__ ? ErrorTypeStrings[type] : type while (cur) { const errorCapturedHooks = cur.ec if (errorCapturedHooks) { for (let i = 0; i < errorCapturedHooks.length; i++) { if ( errorCapturedHooks[i](err, exposedInstance, errorInfo) === false ) { return } } } cur = cur.parent } // app-level handling const appErrorHandler = instance.appContext.config.errorHandler if (appErrorHandler) { callWithErrorHandling( appErrorHandler, null, ErrorCodes.APP_ERROR_HANDLER, [err, exposedInstance, errorInfo] ) return } } logError(err, type, contextVNode, throwInDev) } function logError( err: unknown, type: ErrorTypes, contextVNode: VNode | null, throwInDev = true ) { if (__DEV__) { const info = ErrorTypeStrings[type] if (contextVNode) { pushWarningContext(contextVNode) } warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`) if (contextVNode) { popWarningContext() } // crash in dev by default so it's more noticeable if (throwInDev) { throw err } else Iif (!__TEST__) { console.error(err) } } else E{ // recover in prod to reduce the impact on end-user console.error(err) } } |