No sourcemap-enabled stack trace in loadModules $injectorMinErr (at least not in Chrome) #15590
Description
Do you want to request a feature or report a bug?
Bug
Current behavior + steps to reproduce
- Use webpack or some other concatenation/minification of scripts that benefits of sourcemaps during debugging
- (to be sure that minification errors are thrown) Enable strictDi: true in angular.bootstrap (or use ng-strict-di)
- Attempt to include an angular module that has a reference or other problem. In this case, there is a problem with an undefined variable in config.js
- Notice that the stack trace thrown by loadModules() is referencing to your bundled/minified javascript and not using sourcemaps (latest Chrome):
Error: [$injector:modulerr] Failed to instantiate module app due to:
ReferenceError: env is not defined
at http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:87540:36
at Object.invoke (http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:13342:20)
at runInvokeQueue (http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:13225:36)
at http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:13234:12
at forEach (http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:8852:21)
at loadModules (http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:13215:6)
at createInjector (http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:13137:20)
at doBootstrap (http://localhost:8080/bundle.app.cf5a8012b28c1225c1ed.js:10333:21)
- Also notice that it is possible to click the arrow in the Chrome dev console and see a sourcemaps-enabled stack-trace, but without the entry of config.js where the actual ReferenceError is (it starts from the parent entry to the actual error)
What is the expected behavior?
On step 4, the stack trace should reference the actual source files, so that it is easy to understand where the problem lies in the source code, namely config.js:
ReferenceError: env is not defined
at config.js:1268
at Object.invoke (angular.js:4847)
at runInvokeQueue (angular.js:4730)
at angular.js:4739
at forEach (angular.js:357)
at loadModules (angular.js:4720)
at createInjector (angular.js:4642)
at doBootstrap (angular.js:1838)
...
What is the motivation / use case for changing the behavior?
Easier debugging of module inclusion, especially important when migrating to webpack or other bundler that requires sourcemaps to even have a change debugging in the development-environment.
Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.
Angular 1.6.1 (latest stable)
Chrome 55
Mac OSX El Capitan
Have not tested with latest snapshot.
Other information (e.g. stacktraces, related issues, suggestions how to fix)
A workaround is to replace the following line in angular.js:
throw $injectorMinErr('modulerr', 'Failed to instantiate module {0} due to:\n{1}',
module, e.stack || e.message || e);
with:
throw e;
This yields an understandable stacktrace in the console (shown above).
Note, according to https://bugs.chromium.org/p/chromium/issues/detail?id=376409 "there is no way to fix it for Error.stack property because this property is generated by V8 which know nothing about source map". Despite this, e.stack is preferred as the ErrorConstructor argument over e.
This is evident when running
console.log(e, e.stack);
just before the error is throw. First an error with a sourcemap-enabled stacktrace is displayed in the console, then a stacktrace without sourcemaps.
However, simply replacing "e.stack || e.message || e" with "e" leads to a stack trace with sourcemaps enable but without config.js mentioned:
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
{}
http://errors.angularjs.org/1.6.1/$injector/modulerr?p0=app&p1=%7B%7D
at angular.js:68
at angular.js:4764
at forEach (angular.js:357)
at loadModules (angular.js:4720)
at createInjector (angular.js:4642)
at doBootstrap (angular.js:1838)
at bootstrap (angular.js:1859)