From a7bcb7898f6a4690de56c5ee0c8334cbfc4493e3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 28 Oct 2018 12:09:38 -0400 Subject: [PATCH] refactor: improve error logging --- packages/runtime-core/src/errorHandling.ts | 26 +++++++++++++++------- packages/runtime-core/src/warning.ts | 15 +++++++------ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/packages/runtime-core/src/errorHandling.ts b/packages/runtime-core/src/errorHandling.ts index 863485e4..0ffac29b 100644 --- a/packages/runtime-core/src/errorHandling.ts +++ b/packages/runtime-core/src/errorHandling.ts @@ -1,5 +1,5 @@ import { ComponentInstance } from './component' -import { warn } from './warning' +import { warn, pushWarningContext, popWarningContext } from './warning' import { VNode } from './vdom' import { VNodeFlags } from './flags' @@ -16,7 +16,8 @@ export const enum ErrorTypes { RENDER, WATCH_CALLBACK, NATIVE_EVENT_HANDLER, - COMPONENT_EVENT_HANDLER + COMPONENT_EVENT_HANDLER, + SCHEDULER } const ErrorTypeStrings: Record = { @@ -32,7 +33,8 @@ const ErrorTypeStrings: Record = { [ErrorTypes.RENDER]: 'render function', [ErrorTypes.WATCH_CALLBACK]: 'watcher callback', [ErrorTypes.NATIVE_EVENT_HANDLER]: 'native event handler', - [ErrorTypes.COMPONENT_EVENT_HANDLER]: 'component event handler' + [ErrorTypes.COMPONENT_EVENT_HANDLER]: 'component event handler', + [ErrorTypes.SCHEDULER]: 'scheduler' } export function handleError( @@ -41,6 +43,9 @@ export function handleError( type: ErrorTypes ) { const isFunctional = (instance as VNode)._isVNode + const contextVNode = (isFunctional + ? instance + : (instance as ComponentInstance).$parentVNode) as VNode | null let cur: ComponentInstance | null = null if (isFunctional) { let vnode = instance as VNode | null @@ -61,23 +66,28 @@ export function handleError( cur, err, type, - isFunctional ? null : instance, - isFunctional ? instance : (instance as ComponentInstance).$parentVNode + isFunctional ? null : instance ) if (captured) return } catch (err2) { - logError(err2, ErrorTypes.ERROR_CAPTURED) + logError(err2, ErrorTypes.ERROR_CAPTURED, contextVNode) } } cur = cur.$parent } - logError(err, type) + logError(err, type, contextVNode) } -function logError(err: Error, type: ErrorTypes) { +function logError(err: Error, type: ErrorTypes, contextVNode: VNode | null) { if (__DEV__) { const info = ErrorTypeStrings[type] + if (contextVNode) { + pushWarningContext(contextVNode) + } warn(`Unhandled error${info ? ` in ${info}` : ``}`) + if (contextVNode) { + popWarningContext() + } console.error(err) } else { throw err diff --git a/packages/runtime-core/src/warning.ts b/packages/runtime-core/src/warning.ts index 7c5e73a3..9dcec753 100644 --- a/packages/runtime-core/src/warning.ts +++ b/packages/runtime-core/src/warning.ts @@ -24,15 +24,16 @@ export function warn(msg: string, ...args: any[]) { // TODO warn handler console.warn(`[Vue warn]: ${msg}`, ...args) const trace = getComponentTrace() + if (!trace.length) { + return + } if (console.groupCollapsed) { - trace.forEach((entry, i) => { - const formatted = formatTraceEntry(entry, i) - if (i === 0) { - console.groupCollapsed('at', ...formatted) - } else { - console.log(...formatted) - } + console.groupCollapsed('at', ...formatTraceEntry(trace[0])) + const logs: string[] = [] + trace.slice(1).forEach((entry, i) => { + logs.push(...formatTraceEntry(entry, i + 1)) }) + console.log(...logs) console.groupEnd() } else { const logs: string[] = []