Skip to content

Commit

Permalink
feat: fix vue3 render warning loop (#6014)
Browse files Browse the repository at this point in the history
This patch fixes an infinite loop that would occur in Vue 3 apps with undeclared refs.

Why this happens:
1. Vue3 supports the property `ref` in the second arg of `h` method (see https://cn.vuejs.org/guide/essentials/template-refs.html)
2. When a with an undeclared variable is rendered, Vue3 will call `console.warn` to print the error stack.
3. Sentry instruments `console` (for the `BreadCrumbs` integration), and adds the message to the `Breadcrumb` with `safeJoin`.
4. `safeJoin` converts variables to string. The ref variable is a proxied object via `Proxy` by Vue. so, when `String(value)` is called upon the undefined ref, it will trigger the getter of the Proxy, and which causes Vue3 to call `console.warn` again.
5. This repeats infinitely.

Solutions:
Because there's no reliable way of testing if an object is a `Proxy`, the solution in this case is tailored to this exact scenario. In the breadcrumbs integration code, we check if the passed arguments to the `console.warn` match the specific warning described above. In case of a match, we alter the following argument to not trigger a warning again, thus leaving us with the one warning we want and getting rid of the infinite loop.
  • Loading branch information
Rockergmail authored Oct 24, 2022
1 parent 6df7632 commit d8751dc
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions packages/browser/src/integrations/breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ function _domBreadcrumb(dom: BreadcrumbsOptions['dom']): (handlerData: { [key: s
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function _consoleBreadcrumb(handlerData: { [key: string]: any }): void {
// This is a hack to fix a Vue3-specific bug that causes an infinite loop of
// console warnings. This happens when a Vue template is rendered with
// an undeclared variable, which we try to stringify, ultimately causing
// Vue to issue another warning which repeats indefinitely.
// see: https://github.com/getsentry/sentry-javascript/pull/6010
// see: https://github.com/getsentry/sentry-javascript/issues/5916
for (let i = 0; i < handlerData.args.length; i++) {
if (handlerData.args[i] === 'ref=Ref<') {
handlerData.args[i + 1] = 'viewRef';
break;
}
}
const breadcrumb = {
category: 'console',
data: {
Expand Down

0 comments on commit d8751dc

Please sign in to comment.