18

Using angular 2 with lazy loaded modules, I can receive(for example) 401 HTTP code from server

bootstrap 0b40fee…:101 GET http://localhost:8082/2.chunk.js

Error: Loading chunk 2 failed.
at HTMLScriptElement.onScriptComplete (bootstrap 0b40fee…:91)
at HTMLScriptElement.wrapFn (zone.js:1032)
at ZoneDelegate.invokeTask (zone.js:414)
at Object.onInvokeTask (core.es5.js:4119)
at ZoneDelegate.invokeTask (zone.js:413)
at Zone.runTask (zone.js:181)
at HTMLScriptElement.ZoneTask.invoke (zone.js:476)

How to handle this error?

smie
  • 592
  • 1
  • 9
  • 25
  • How do you serve your application? With ng serve or stg else? This kinda problem may be related with wrong path, can you give more detail? – ulubeyn May 17 '17 at 21:52
  • Path is fine. Question is how to handle load chunks(webpack) errors. Reason can be any HTTP error code – smie May 18 '17 at 04:26
  • There's a similar question here, focused more on network connection loss than 401 type errors. Also there's a NavigationError event which possibly you could hook into, and at least get the URL. – Simon_Weaver Feb 21 '19 at 19:26

9 Answers9

21

Check my answer for details

  • Workaround to bypass this chunk fails error => Programmatically force app to reload if chunks failed error occurs using global error handler.

import { ErrorHandler } from '@angular/core';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {

  handleError(error: any): void {
   const chunkFailedMessage = /Loading chunk [\d]+ failed/;

    if (chunkFailedMessage.test(err.message)) {
      window.location.reload();
    }
  }
}
  • Provide it in our root module to change default behavior in our app, so instead of using default ErrorHandler class we are using our custom GlobalErrorHandler class.

@NgModule({   
  providers: [{provide: ErrorHandler, useClass: GlobalErrorHandler}]
})
Khaled Lela
  • 7,831
  • 6
  • 45
  • 73
  • It occurs during navigation. Is it possible to reload to destination page? – Walter Luszczyk Oct 24 '19 at 06:34
  • 1
    if you already opened app in browser, and new build deploy made when you tries to navigate route loading chunk failed issue occurs, because browser is using already cached chunks instead of newly deployed. – Khaled Lela Oct 24 '19 at 09:46
  • 3
    Hard refresh (control + shift + R) page after new build deploy to load new chunks – Khaled Lela Oct 24 '19 at 09:47
  • @WalterLuszczyk you can check my answer for a solution that should automatically handle redirection to the desired page for the user. – Questioning Apr 30 '20 at 15:22
5

I was having the same problem so I investigated. I found the solution. This happened to me when I redeployed to another server and the chunk had a [hash].

You can catch the error either in a catch all like this:

ngOnInit() {
    if (!this.previousRouterErrorHandler) {
        this.previousRouterErrorHandler = this.router.errorHandler;
        let that = this;
        this.router.errorHandler = function (err: any) {
            // Handle here. err.message == "Loading chunk chunk-name failed."

            return that.previousRouterErrorHandler.apply(that.previousRouterErrorHandler, arguments);
        };
    }
}

Or directly at the link which navigated

click() {
    this.router.navigate(['/lazy-route'])
        .catch(err => {
            // Handle here
        });
}
jsgoupil
  • 3,788
  • 3
  • 38
  • 53
  • Thanks! Using your idea, I just simply set up a function for this.router.errorHandler and this way I could catch these chunk errors. – jeti Apr 11 '18 at 07:21
  • 2
    But how do you handle this case? I mean, it does not solve the problem itself, it just helps you to catch it. – Kanso Code Sep 01 '18 at 14:51
  • It's not the best, but I throw a popover saying they have to refresh with a message "We got an update, finish what you are doing and refresh the page." It's unfortunate Angular does not support something better out of the box. – jsgoupil Sep 03 '18 at 04:16
5

Here is my solution for this. I inject this service as a singleton in my app / core module.

It waits for instances of NavigationError from the router, checks if they are ChunkLoadError's and then does a redirect to the place the user wanted to go to anyway.

// Angular
import { Injectable, OnDestroy } from '@angular/core';
import { Router, NavigationError } from '@angular/router';
// Rxjs
import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';

@Injectable()
export class ChunkErrorHandler implements OnDestroy {
  private subscription: Subscription;

  constructor(router: Router) {
    this.subscription = router.events
      .pipe(filter(event => event instanceof NavigationError))
      .subscribe(event => {
        this.handleRouterErrors(event as NavigationError);
      });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  private handleRouterErrors(event: NavigationError) {
    if (event.error.name === 'ChunkLoadError') {
      window.location.href = `${window.location.origin}${event.url}`;
    }
  }
}
Questioning
  • 1,903
  • 1
  • 29
  • 50
1

It happen when when deploy new code.The manifest.js which holds the files and hashes doesn't update without refreshing and when it loads a chunk it obviously uses the old hash from manifest.js.

So while catching error we can do force reload with given url :-

click() {
      this.router.navigate(['/lazy-route'])
           .catch(err => {
              // Handle here
              // reload with given route
              // window.location.pathname('/lazy-route');

              // OR
              // reset existing route(containing query params) with given route and force reload
               window.history.pushState({}, document.title, '/lazy-route' );
               window.location.reload();
           });
 }
vijayliebe
  • 158
  • 6
0

chunk related errors can be raised by any environment or routing related issues making them hard to debunk.

In my case, the amount of data moving in my PWA was too much to handle by the angular router. It was flooding the headers of the js chunks getters and therefore raising bad_request errors.

I suggest you to check out those network calls (getters of chunks.js like http://localhost:xxxx/158.js) for anything unusual in headers and refactor sketchy stuff in your current dev environment, since it's a real black hole time to investigate the source of the error by yourself.

Hope that'll help

Eredian
  • 11
  • 3
0

check out Catch Storage, i guess service worker save some thing in catch storage

joshua
  • 1
  • 1
0
console.log(Object.entries(error));

this help me to understand what's inside the error is

rejection, promise, zone, task

and below is my solution:

handleError(error) {
        switch (error?.rejection?.name) {
            case 'ChunkLoadError':
                window.location.href = window.location.href;
                break;

            default:
                break;
        }
    }
Tommy Kao
  • 11
  • 1
-1

In my case, I was putting my files in an S3 bucket. I kept getting this error because it was calling the wrong filenames all together and returning an html error response.

At some point I let the IT team know what was happening. They were like, let's invalidate the cache on CloudFront... What?! Yeah! Let's do that...

Moral of the story, if you've been searching the web for answers to this error and can't find any, check with the IT team or any place that the index.html file might be getting cached.

christo8989
  • 6,442
  • 5
  • 37
  • 43
-5

this probably means unhandled exception. you have to handle error responses (4xx, 5xx status codes) from server in whatever way you want: show error message somewhere, redirect to some page, do anything but not leave it unhandled.

for example:

return this.http.get(requestDetails)
          .map(res => res.json())
          .catch(err => {
console.log('server error:', err)
Observable.throw(err);
});
dee zg
  • 13,793
  • 10
  • 42
  • 82