question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Why are angular elements swallowing error?

See original GitHub issue

I have the simplest possible angular element within an angular project.

I throw error in component belonging to angular element as follows:

dashboard-tile.component.ts: (referenced in index.html as <dashboard-tile a="100" b="50" c="25"></dashboard-tile>)

  ngOnInit() {
    debugger;
    throw "this is an error";
  }

But I see no error in chrome console.

Link to video.

However, if I start to use this component as a regular component, I immediately get an error on console. So this is likely an angular-element issue.

Link to github repo containg the code

Tested on both chrome and firefox and its reproducible so its not browser isssue.

Other info:

Angular CLI: 7.1.4 Node: 10.14.2 OS: win32 x64 Angular: 7.1.4 … animations, cli, common, compiler, compiler-cli, core, forms … language-service, platform-browser, platform-browser-dynamic … router

Package Version

@angular-devkit/architect 0.11.4 @angular-devkit/build-angular 0.11.4 @angular-devkit/build-optimizer 0.11.4 @angular-devkit/build-webpack 0.11.4 @angular-devkit/core 7.1.4 @angular-devkit/schematics 7.1.4 @angular/elements 7.2.8 @ngtools/webpack 7.1.4 @schematics/angular 7.1.4 @schematics/update 0.11.4 rxjs 6.3.3 typescript 3.1.6 webpack 4.23.1

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:3
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
gkalpakcommented, Jun 2, 2020

This still seems to be an issue in v9: Updated StackBlitz

@alexzuza is right: This is because the ngZone.onError subscription that forwards errors to ErrorHandler has not been created when the module is instantiated. This has to be this way, because we need the module instance to retrieve the ErrorHandler, before subscribing to ngZone.onError.

This is not specific to @angular/elements btw. Any error thrown inside the root module’s constructor will get swallowed.

We should document this. (Adding the comp: docs label.) Additionally, we could also subscribe to ngZone.onError and just console.error() any errors while instantiating the root module (but that might be a breaking change).

Finally, the work around is obviously to defer the code until after the module has been instantiated. There are many ways to achieve this, such as (in no particular order):

  • Ensuring the code is run asynchronously - e.g. by wrapping the code in setTimeout() or Promise.resolve().then():

    expost class AppModule {
      constructor() {
        setTimeout(() => /* Error-throwing code. */);
      }
    }
    
  • Move the code from AppModule#constructor() to AppComponent#constructor(). (BTW, this is what we show in the Angular Element guide live example.)

    export class AppModule {
      constructor() { /* Nothing here. */ }
    }
    
    export class AppComponent  {
      constructor() { /* Error-throwing code. */ }
    }
    
  • Move the code to an APP_BOOTSTRAP_LISTENER:

    @NgModule({
      ...
      providers: [
        {
          provide: APP_BOOTSTRAP_LISTENER,
          useFactory: (...injectedDeps) =>
            () => /* Error-throwing code. */,
          deps: [/* Deps... */],
          multi: true,
        },
      ],
    })
    export class AppModule {
      constructor() { /* Nothing here. */ }
    }
    
  • Moving the code to the module’s ngDoBootstrap() method. Since ngDoBootstrap() cannot be used in conjuction with @NgModule > bootstrap, one would also have to move bootstraping or AppComponent to ngDoBootstrap():

    @NgModule({
      ...
      bootstrap: [ /* Nothing here. */ ],
    })
    export class AppModule implements DoBootstrap {
      constructor() { /* Nothing here. */ }
    
      ngDoBootstrap(appRef: ApplicationRef): void {
        // "Manually" bootstrap `AppComponent`.
        appRef.bootstrap(AppComponent);
    
        /* Error-throwing code. */
      }
    }
    
1reaction
alexzuzacommented, Jun 2, 2020

I guess that there is no subscription to ngZone.onError yet where you’re defining custom elements inside AppModule constructor.

Try moving your code to ngDoBootstrap method and you will be able to see your error.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why angular elements are swallowing error? - Stack Overflow
In my case Angular was swallowing the exceptions because I was calling the createCustomElement() from '@angular/elements' in the constructor ...
Read more >
Angular Swallowing Errors - StackBlitz
Never miss an error.
Read more >
Debugging Angular Applications from the Console - | juri.dev
Angular 1 & 2 both have horrifically awful error-handling and debuggability. Like, what's up with exception swallowing?! That's a prescription ...
Read more >
Why are polyfills in angular production builds behaving ...
Why angular elements are swallowing error? ... In angular application, while inspecting an element via chrome dev tool, why do I not see...
Read more >
Lessons learned from Angular - Mithril
The main problem with directives is their sheer complexity: when writing a directive, you quick stumble across things like scope isolation and $ ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found