Angular 2. Error: Loading chunk failed

Viewed 33457

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?

8 Answers

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}]
})

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
        });
}

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}`;
    }
  }
}

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();
           });
 }

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

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

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.

Related