fix(exception_handler): log errors that are thrown by the compiler

This commit is contained in:
vsavkin 2015-08-05 10:37:11 -07:00
parent b4a062983b
commit 07b9be798c
4 changed files with 25 additions and 20 deletions

View File

@ -158,13 +158,8 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
]; ];
} }
export function createNgZone(handler: ExceptionHandler): NgZone { export function createNgZone(): NgZone {
// bootstrapErrorReporter is needed because we cannot use custom exception handler return new NgZone({enableLongStackTrace: assertionsEnabled()});
// configured via DI until the root Injector has been created.
var bootstrapErrorReporter = (exception, stackTrace) => handler.call(exception, stackTrace);
var zone = new NgZone({enableLongStackTrace: assertionsEnabled()});
zone.overrideOnErrorHandler(bootstrapErrorReporter);
return zone;
} }
/** /**
@ -299,16 +294,16 @@ export function commonBootstrap(
BrowserDomAdapter.makeCurrent(); BrowserDomAdapter.makeCurrent();
wtfInit(); wtfInit();
var bootstrapProcess = PromiseWrapper.completer(); var bootstrapProcess = PromiseWrapper.completer();
var zone = createNgZone(new ExceptionHandler(DOM, isDart ? false : true)); var zone = createNgZone();
zone.run(() => {
// TODO(rado): prepopulate template cache, so applications with only
// index.html and main.js are possible.
var appInjector = _createAppInjector(appComponentType, componentInjectableBindings, zone); zone.run(() => {
var exceptionHandler = appInjector.get(ExceptionHandler); var exceptionHandler;
zone.overrideOnErrorHandler((e, s) => exceptionHandler.call(e, s));
try { try {
var appInjector = _createAppInjector(appComponentType, componentInjectableBindings, zone);
exceptionHandler = appInjector.get(ExceptionHandler);
zone.overrideOnErrorHandler((e, s) => exceptionHandler.call(e, s));
var compRefToken: Promise<any> = appInjector.get(appComponentRefPromiseToken); var compRefToken: Promise<any> = appInjector.get(appComponentRefPromiseToken);
var tick = (componentRef) => { var tick = (componentRef) => {
var appChangeDetector = internalView(componentRef.hostView).changeDetector; var appChangeDetector = internalView(componentRef.hostView).changeDetector;
@ -327,10 +322,17 @@ export function commonBootstrap(
PromiseWrapper.then(tickResult, null, PromiseWrapper.then(tickResult, null,
(err, stackTrace) => { bootstrapProcess.reject(err, stackTrace); }); (err, stackTrace) => { bootstrapProcess.reject(err, stackTrace); });
} catch (e) { } catch (e) {
if (isPresent(exceptionHandler)) {
exceptionHandler.call(e, e.stack);
} else {
// The error happened during the creation of an injector, most likely because of a bug in
// DI.
// We cannot use the provided exception handler, so we default to writing to the DOM.
DOM.logError(e);
}
bootstrapProcess.reject(e, e.stack); bootstrapProcess.reject(e, e.stack);
} }
}); });
return bootstrapProcess.promise; return bootstrapProcess.promise;
} }

View File

@ -29,10 +29,8 @@ import {
import {createNgZone} from 'angular2/src/core/application_common'; import {createNgZone} from 'angular2/src/core/application_common';
import {WorkerElementRef} from 'angular2/src/web-workers/shared/api'; import {WorkerElementRef} from 'angular2/src/web-workers/shared/api';
import {AnchorBasedAppRootUrl} from 'angular2/src/services/anchor_based_app_root_url'; import {AnchorBasedAppRootUrl} from 'angular2/src/services/anchor_based_app_root_url';
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
import {Injectable} from 'angular2/di'; import {Injectable} from 'angular2/di';
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
import {DOM} from 'angular2/src/dom/dom_adapter';
import { import {
serializeMouseEvent, serializeMouseEvent,
serializeKeyboardEvent, serializeKeyboardEvent,
@ -46,7 +44,7 @@ import {
*/ */
export function bootstrapUICommon(bus: MessageBus) { export function bootstrapUICommon(bus: MessageBus) {
BrowserDomAdapter.makeCurrent(); BrowserDomAdapter.makeCurrent();
var zone = createNgZone(new ExceptionHandler(DOM)); var zone = createNgZone();
zone.run(() => { zone.run(() => {
var injector = createInjector(zone); var injector = createInjector(zone);
var webWorkerMain = injector.get(WebWorkerMain); var webWorkerMain = injector.get(WebWorkerMain);

View File

@ -139,7 +139,7 @@ export function bootstrapWebworkerCommon(
componentInjectableBindings: List<Type | Binding | List<any>> = null): Promise<ApplicationRef> { componentInjectableBindings: List<Type | Binding | List<any>> = null): Promise<ApplicationRef> {
var bootstrapProcess: PromiseCompleter<any> = PromiseWrapper.completer(); var bootstrapProcess: PromiseCompleter<any> = PromiseWrapper.completer();
var zone = createNgZone(new ExceptionHandler(new PrintLogger())); var zone = createNgZone();
zone.run(() => { zone.run(() => {
// TODO(rado): prepopulate template cache, so applications with only // TODO(rado): prepopulate template cache, so applications with only
// index.html and main.js are possible. // index.html and main.js are possible.

View File

@ -92,11 +92,16 @@ export function main() {
it('should throw if bootstrapped Directive is not a Component', it('should throw if bootstrapped Directive is not a Component',
inject([AsyncTestCompleter], (async) => { inject([AsyncTestCompleter], (async) => {
var refPromise = bootstrap(HelloRootDirectiveIsNotCmp, [testBindings]); var logger = new _ArrayLogger();
var exceptionHandler = new ExceptionHandler(logger, false);
var refPromise =
bootstrap(HelloRootDirectiveIsNotCmp,
[testBindings, bind(ExceptionHandler).toValue(exceptionHandler)]);
PromiseWrapper.then(refPromise, null, (exception) => { PromiseWrapper.then(refPromise, null, (exception) => {
expect(exception).toContainError( expect(exception).toContainError(
`Could not load '${stringify(HelloRootDirectiveIsNotCmp)}' because it is not a component.`); `Could not load '${stringify(HelloRootDirectiveIsNotCmp)}' because it is not a component.`);
expect(logger.res.join("")).toContain("Could not load");
async.done(); async.done();
return null; return null;
}); });