feat(core): provide an error context when an exception happens in an error handler
This commit is contained in:
@@ -1043,9 +1043,7 @@ class TestDispatcher implements ChangeDispatcher {
|
||||
|
||||
notifyOnAllChangesDone() { this.onAllChangesDoneCalled = true; }
|
||||
|
||||
getDebugContext(a, b) {
|
||||
return {}
|
||||
}
|
||||
getDebugContext(a, b) { return null; }
|
||||
|
||||
_asString(value) { return (isBlank(value) ? 'null' : value.toString()); }
|
||||
}
|
||||
|
||||
@@ -66,12 +66,14 @@ class HelloRootMissingTemplate {
|
||||
class HelloRootDirectiveIsNotCmp {
|
||||
}
|
||||
|
||||
class _NilLogger {
|
||||
log(s: any): void {}
|
||||
logGroup(s: any): void {}
|
||||
class _ArrayLogger {
|
||||
res: any[] = [];
|
||||
log(s: any): void { this.res.push(s); }
|
||||
logGroup(s: any): void { this.res.push(s); }
|
||||
logGroupEnd(){};
|
||||
}
|
||||
|
||||
|
||||
export function main() {
|
||||
var fakeDoc, el, el2, testBindings, lightDom;
|
||||
|
||||
@@ -90,7 +92,7 @@ export function main() {
|
||||
|
||||
it('should throw if bootstrapped Directive is not a Component',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootDirectiveIsNotCmp, testBindings);
|
||||
var refPromise = bootstrap(HelloRootDirectiveIsNotCmp, [testBindings]);
|
||||
|
||||
PromiseWrapper.then(refPromise, null, (exception) => {
|
||||
expect(exception).toContainError(
|
||||
@@ -101,10 +103,11 @@ export function main() {
|
||||
}));
|
||||
|
||||
it('should throw if no element is found', inject([AsyncTestCompleter], (async) => {
|
||||
// do not print errors to the console
|
||||
var e = new ExceptionHandler(new _NilLogger());
|
||||
var logger = new _ArrayLogger();
|
||||
var exceptionHandler = new ExceptionHandler(logger, IS_DARTIUM ? false : true);
|
||||
|
||||
var refPromise = bootstrap(HelloRootCmp, [bind(ExceptionHandler).toValue(e)]);
|
||||
var refPromise =
|
||||
bootstrap(HelloRootCmp, [bind(ExceptionHandler).toValue(exceptionHandler)]);
|
||||
PromiseWrapper.then(refPromise, null, (reason) => {
|
||||
expect(reason.message).toContain('The selector "hello-app" did not match any elements');
|
||||
async.done();
|
||||
@@ -112,6 +115,23 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
if (DOM.supportsDOMEvents()) {
|
||||
it('should invoke the default exception handler when bootstrap fails',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var logger = new _ArrayLogger();
|
||||
var exceptionHandler = new ExceptionHandler(logger, IS_DARTIUM ? false : true);
|
||||
|
||||
var refPromise =
|
||||
bootstrap(HelloRootCmp, [bind(ExceptionHandler).toValue(exceptionHandler)]);
|
||||
PromiseWrapper.then(refPromise, null, (reason) => {
|
||||
expect(logger.res.join(""))
|
||||
.toContain('The selector "hello-app" did not match any elements');
|
||||
async.done();
|
||||
return null;
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
it('should create an injector promise', () => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
expect(refPromise).not.toBe(null);
|
||||
|
||||
@@ -16,7 +16,9 @@ import {
|
||||
containsRegexp,
|
||||
stringifyElement,
|
||||
TestComponentBuilder,
|
||||
fakeAsync
|
||||
fakeAsync,
|
||||
tick,
|
||||
clearPendingTimers
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
|
||||
@@ -1200,7 +1202,7 @@ export function main() {
|
||||
expect(c.injector).toBeAnInstanceOf(Injector);
|
||||
expect(c.expression).toContain("one.two.three");
|
||||
expect(c.context).toBe(rootTC.componentInstance);
|
||||
expect(c.locals["local"]).not.toBeNull();
|
||||
expect(c.locals["local"]).toBeDefined();
|
||||
}
|
||||
|
||||
async.done();
|
||||
@@ -1226,6 +1228,38 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
if (DOM.supportsDOMEvents()) { // this is required to use fakeAsync
|
||||
it('should provide an error context when an error happens in an event handler',
|
||||
inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => {
|
||||
|
||||
tcb = tcb.overrideView(MyComp, new viewAnn.View({
|
||||
template: `<span emitter listener (event)="throwError()" #local></span>`,
|
||||
directives: [DirectiveEmitingEvent, DirectiveListeningEvent]
|
||||
}));
|
||||
|
||||
var rootTC;
|
||||
tcb.createAsync(MyComp).then(root => { rootTC = root; });
|
||||
tick();
|
||||
|
||||
var tc = rootTC.componentViewChildren[0];
|
||||
tc.inject(DirectiveEmitingEvent).fireEvent("boom");
|
||||
|
||||
try {
|
||||
tick();
|
||||
throw "Should throw";
|
||||
} catch (e) {
|
||||
clearPendingTimers();
|
||||
|
||||
var c = e.context;
|
||||
expect(DOM.nodeName(c.element).toUpperCase()).toEqual("SPAN");
|
||||
expect(DOM.nodeName(c.componentElement).toUpperCase()).toEqual("DIV");
|
||||
expect(c.injector).toBeAnInstanceOf(Injector);
|
||||
expect(c.context).toBe(rootTC.componentInstance);
|
||||
expect(c.locals["local"]).toBeDefined();
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
if (!IS_DARTIUM) {
|
||||
it('should report a meaningful error when a directive is undefined',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder,
|
||||
@@ -1513,6 +1547,8 @@ class MyComp {
|
||||
this.ctxNumProp = 0;
|
||||
this.ctxBoolProp = false;
|
||||
}
|
||||
|
||||
throwError() { throw 'boom'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'child-cmp', properties: ['dirProp'], viewInjector: [MyService]})
|
||||
|
||||
Reference in New Issue
Block a user