getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.86k stars 1.55k forks source link

@sentry/angular cause infinite re-render loop #2974

Closed nicowernli closed 3 years ago

nicowernli commented 3 years ago

Package + Version

Version:

^5.26.0

Description

When initializing Sentry library Angular app won't stop to re-render. The Sentry intializer starts an infinite re-render loop that start consuming a lot of CPU and if there any sort of console.log or something like that in each interaction could eventually kill the browser.

This can be reproducible in a brand new angular-cli app

// main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { init } from '@sentry/angular';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

init({ dsn: '__MY_SDN__' });

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));
// app.component.ts
import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  ngDoCheck(): void {
    console.log("re rendering for ever");
  }
}
rodolfoBee commented 3 years ago

This is currently a known issue, the workaround is to disable console breadcrumbs to prevent the loop:

Sentry.init({
  // ...
  integrations: [new Sentry.Integrations.Breadcrumbs({ console: false })]
  // ...
})

Original comment

intellix commented 3 years ago

The above comment doesn't seem to help me. Getting an infinite loop of logs using the Sentry error handler:

{
  provide: ErrorHandler,
  useValue: Sentry.createErrorHandler({ showDialog: false }),
},

This doesn't happen if I create a custom handler that re-throws the error like so:

import { ErrorHandler, Injectable } from '@angular/core';
import * as Sentry from '@sentry/browser';

@Injectable()
export class SentryErrorHandler implements ErrorHandler {
  handleError(error: Error & { originalError?: Error }) {
    Sentry.captureException(error.originalError || error);
    console.error(error);
    if (error instanceof TypeError) {
      throw error;
    }
  }
}

Error:

TypeError: Cannot read property 'accountId' of undefined
    at PaymentViewComponent_ng_container_0_Template (payment-view.component.html:132)
    at executeTemplate (core.js:9517)
    at refreshView (core.js:9386)
    at refreshEmbeddedViews (core.js:10506)
    at refreshView (core.js:9410)
    at refreshComponent (core.js:10552)
    at refreshChildComponents (core.js:9183)
    at refreshView (core.js:9436)
    at refreshEmbeddedViews (core.js:10506)
    at refreshView (core.js:9410)
    at refreshComponent (core.js:10552)
    at refreshChildComponents (core.js:9183)
    at refreshView (core.js:9436)
    at refreshComponent (core.js:10552)
    at refreshChildComponents (core.js:9183)
    at refreshView (core.js:9436)
    at renderComponentOrTemplate (core.js:9500)
    at tickRootContext (core.js:10726)
    at detectChangesInRootView (core.js:10751)
    at RootViewRef.detectChanges (core.js:22769)
    at ApplicationRef.tick (core.js:29491)
    at core.js:29375

Edit: You can disregard my message about infinite looping as it was related to my app and not caused by Sentry

kamilogorek commented 3 years ago

@intellix I wasn't able to reproduce the issue locally. Can you provide some kind of repro case? I'd also recommend moving to @sentry/angular if that's possible - https://docs.sentry.io/platforms/javascript/guides/angular/

kamilogorek commented 3 years ago

Closing the issue as a part of large repository cleanup, due to it being inactive and/or outdated. Please do not hesitate to ping me if it is still relevant, and I will happily reopen and work on it. Cheers!