webpack: Webpack import cannot be caught

Do you want to request a feature or report a bug? Bug

What is the current behavior? Currently, if you dynamically call the import function and you are offline, the catch function is never called. Webpack generates an uncaught exception.

import('./my-component')
  .then(module => {})
  .catch(err => console.log(err)

If the current behavior is a bug, please provide the steps to reproduce. Step 1)

window.loadChunk = () => {
  import('./my-component')
    .then(module => {})
    .catch(err => console.log(err))
}

Step 2) Load the bundle on the page, you should now have available loadChunk function

Step 3) Put your browser in “offline mode”

Step 4) call the loadChunk() function

What is the expected behavior? Expected behavior is that the catch function is called and error logged.

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System. Using: Webpack v3.3.0 This happens because the import function is converted into a Promise that wraps the require.ensure. Any time the require.ensure rejects the promise, it automatically calls the ensure’s OnError callback which throws an exception. Async exceptions are not caught by the parent Promise, resulting in the bug above.

// var prom = import('./my-component)
var prom = new Promise(function (resolve) {
  __webpack_require__.e/* require.ensure */(1).then((function (require) {
    resolve(__webpack_require__( /* webpackChunkName: "my-component" */697));
  }).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
});

// __webpack_require__.oe (On Error)
__webpack_require__.oe = function(err) { console.error(err); throw err; };

Please let me know if I’m missing something, maybe in the configuration, or if this is really a bug.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 15 (1 by maintainers)

Most upvoted comments

Almost a year later… Has anybody else figured out a way around this?

The Code Splitting guide seems to suggest that you should be able to .catch() the promise…

   return import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => {
     var element = document.createElement('div');
     var _ = _.default;

     element.innerHTML = _.join(['Hello', 'webpack'], ' ');

     return element;

   }).catch(error => 'An error occurred while loading the component');

But I’ll be darned if I can figure out how!

import('./_no_such_file_.js')
  .then(mod => console.log("IMPORTED", mod))
  .catch(err => console.log("ERROR", err))

… and:

try {
  import('./_no_such_file_.js')
    .then(mod => console.log("IMPORTED", mod))
    .catch(err => console.log("ERROR", err))
} catch(e) {
  console.log("CAUGHT", e)
}

… both result in: Module not found: Error: Can't resolve './_no_such_file_.js' and produce unusable bundles. 😦

It is again a year later… I understand @taddei solved this in the initial comments, but can you guys be any more vague (while clearly others have this issue still)?

@sokra are you indicating that using babel plugin dynamic-import-webpack essentially breaks catching import() errors? If so, document that somewhere, please.

Can you confirm, @taddei ? ^

In any case, removing dynamic-import-webpack (for me) still breaks (still using @babel/plugin-syntax-dynamic-import though.)

me too

I’m still searching. Lol.

import('./_no_such_file_.js')
  .then(mod => console.log("IMPORTED", mod))
  .catch(err => console.log("ERROR", err))

FWIW — I don’t know what changed, or when, but this now seems to DWIM:

import('./_no_such_file_.js')
  .catch(e => console.log("CAUGHT"))
prompt% npx webpack; echo "RC=$?"
CAUGHT
RC=0

prompt% npx webpack --version
4.43.0

«shrug»

Okay, so I was trying to create a fallback import, in case a file wasn’t exisitng.

This actualy solved my issue : https://github.com/webpack/webpack/issues/6680#issuecomment-370800037

I was testing with an hardcoded value: ex :

try {

        md = await import(`test.md`)
      } catch (e) {
        md = await import(`~/content/us/template-guide.md`)
      }

You have to test with variables :

try {

        md = await import(`${Math.random()}`)
      } catch (e) {
        md = await import(`~/content/us/template-guide.md`)
      }

I am still having this issue. Any news? It appears that the underlying Promise doesn’t “reject” when an error occurs upon loading the module.

Thanks