-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vue): Rework tracing and add support for Vue 3 (#3804)
* feat(vue): Rework tracing and add support for Vue 3
- Loading branch information
1 parent
41cf211
commit 14ccb55
Showing
13 changed files
with
440 additions
and
4,824 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { ViewModel } from './types'; | ||
|
||
// Vendored directly from https://github.com/vuejs/vue/blob/master/src/core/util/debug.js with types only changes. | ||
const classifyRE = /(?:^|[-_])(\w)/g; | ||
const classify = (str: string): string => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, ''); | ||
|
||
const ROOT_COMPONENT_NAME = '<Root>'; | ||
const ANONYMOUS_COMPONENT_NAME = '<Anonymous>'; | ||
|
||
const repeat = (str: string, n: number): string => { | ||
let res = ''; | ||
while (n) { | ||
if (n % 2 === 1) { | ||
res += str; | ||
} | ||
if (n > 1) { | ||
str += str; // eslint-disable-line no-param-reassign | ||
} | ||
n >>= 1; // eslint-disable-line no-bitwise, no-param-reassign | ||
} | ||
return res; | ||
}; | ||
|
||
export const formatComponentName = (vm?: ViewModel, includeFile?: boolean): string => { | ||
if (!vm) { | ||
return ANONYMOUS_COMPONENT_NAME; | ||
} | ||
|
||
if (vm.$root === vm) { | ||
return ROOT_COMPONENT_NAME; | ||
} | ||
|
||
const options = vm.$options; | ||
|
||
let name = options.name || options._componentTag; | ||
const file = options.__file; | ||
if (!name && file) { | ||
const match = file.match(/([^/\\]+)\.vue$/); | ||
if (match) { | ||
name = match[1]; | ||
} | ||
} | ||
|
||
return ( | ||
(name ? `<${classify(name)}>` : ANONYMOUS_COMPONENT_NAME) + (file && includeFile !== false ? ` at ${file}` : ``) | ||
); | ||
}; | ||
|
||
export const generateComponentTrace = (vm?: ViewModel): string => { | ||
if (vm?._isVue && vm?.$parent) { | ||
const tree = []; | ||
let currentRecursiveSequence = 0; | ||
while (vm) { | ||
if (tree.length > 0) { | ||
const last = tree[tree.length - 1] as any; | ||
if (last.constructor === vm.constructor) { | ||
currentRecursiveSequence += 1; | ||
vm = vm.$parent; // eslint-disable-line no-param-reassign | ||
continue; | ||
} else if (currentRecursiveSequence > 0) { | ||
tree[tree.length - 1] = [last, currentRecursiveSequence]; | ||
currentRecursiveSequence = 0; | ||
} | ||
} | ||
tree.push(vm); | ||
vm = vm.$parent; // eslint-disable-line no-param-reassign | ||
} | ||
|
||
const formattedTree = tree | ||
.map( | ||
(vm, i) => | ||
`${(i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + | ||
(Array.isArray(vm) | ||
? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)` | ||
: formatComponentName(vm))}`, | ||
) | ||
.join('\n'); | ||
|
||
return `\n\nfound in\n\n${formattedTree}`; | ||
} | ||
|
||
return `\n\n(found in ${formatComponentName(vm)})`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { getCurrentHub } from '@sentry/browser'; | ||
|
||
import { formatComponentName, generateComponentTrace } from './components'; | ||
import { Options, ViewModel, Vue } from './types'; | ||
|
||
export const attachErrorHandler = (app: Vue, options: Options): void => { | ||
const { errorHandler, warnHandler, silent } = app.config; | ||
|
||
app.config.errorHandler = (error: Error, vm: ViewModel, lifecycleHook: string): void => { | ||
const componentName = formatComponentName(vm, false); | ||
const trace = vm ? generateComponentTrace(vm) : ''; | ||
const metadata: Record<string, unknown> = { | ||
componentName, | ||
lifecycleHook, | ||
trace, | ||
}; | ||
|
||
if (options.attachProps) { | ||
// Vue2 - $options.propsData | ||
// Vue3 - $props | ||
metadata.propsData = vm.$options.propsData || vm.$props; | ||
} | ||
|
||
// Capture exception in the next event loop, to make sure that all breadcrumbs are recorded in time. | ||
setTimeout(() => { | ||
getCurrentHub().withScope(scope => { | ||
scope.setContext('vue', metadata); | ||
getCurrentHub().captureException(error); | ||
}); | ||
}); | ||
|
||
if (typeof errorHandler === 'function') { | ||
errorHandler.call(app, error, vm, lifecycleHook); | ||
} | ||
|
||
if (options.logErrors) { | ||
const hasConsole = typeof console !== 'undefined'; | ||
const message = `Error in ${lifecycleHook}: "${error && error.toString()}"`; | ||
|
||
if (warnHandler) { | ||
warnHandler.call(null, message, vm, trace); | ||
} else if (hasConsole && !silent) { | ||
// eslint-disable-next-line no-console | ||
console.error(`[Vue warn]: ${message}${trace}`); | ||
} | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
export * from '@sentry/browser'; | ||
|
||
export { init } from './sdk'; | ||
export { vueRouterInstrumentation } from './vuerouter'; | ||
export { vueRouterInstrumentation } from './router'; | ||
export { attachErrorHandler } from './errorhandler'; | ||
export { createTracingMixins } from './tracing'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.