diff --git a/modules/angular2/src/core/compiler/proto_view_factory.js b/modules/angular2/src/core/compiler/proto_view_factory.js index 37be908cbd..d13013d8a8 100644 --- a/modules/angular2/src/core/compiler/proto_view_factory.js +++ b/modules/angular2/src/core/compiler/proto_view_factory.js @@ -109,11 +109,11 @@ export class ProtoViewFactory { ); // text nodes for (var i=0; i { - protoView.bindElementProperty(astWithSource.ast, propertyName); + protoView.bindElementProperty(astWithSource, propertyName); }); // events protoView.bindEvent(renderElementBinder.eventBindings, -1); @@ -136,7 +136,7 @@ export class ProtoViewFactory { // TODO: these setters should eventually be created by change detection, to make // it monomorphic! var setter = reflector.setter(propertyName); - protoView.bindDirectiveProperty(i, astWithSource.ast, propertyName, setter); + protoView.bindDirectiveProperty(i, astWithSource, propertyName, setter); }); // directive events protoView.bindEvent(renderDirectiveMetadata.eventBindings, i); diff --git a/modules/angular2/src/render/dom/view/proto_view_builder.js b/modules/angular2/src/render/dom/view/proto_view_builder.js index 7ac7301965..b458c6bbb2 100644 --- a/modules/angular2/src/render/dom/view/proto_view_builder.js +++ b/modules/angular2/src/render/dom/view/proto_view_builder.js @@ -248,7 +248,7 @@ export class EventBuilder extends AstTransformer { // var adjustedAst = astWithSource.ast.visit(this); var adjustedAst = source.ast; var fullName = isPresent(target) ? target + EVENT_TARGET_SEPARATOR + name : name; - var result = new api.EventBinding(fullName, new ASTWithSource(adjustedAst, source.source, '')); + var result = new api.EventBinding(fullName, new ASTWithSource(adjustedAst, source.source, source.location)); var event = new Event(name, target, fullName); if (isBlank(target)) { ListWrapper.push(this.localEvents, event); diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js index d04be4ea3b..9ed8a40f41 100644 --- a/modules/angular2/test/core/compiler/integration_spec.js +++ b/modules/angular2/test/core/compiler/integration_spec.js @@ -731,8 +731,49 @@ export function main() { async.done(); }); })); + }); + describe("error handling", () => { + it('should specify a location of an error that happened during change detection (text)', + inject([TestBed, AsyncTestCompleter], (tb, async) => { + + tb.overrideView(MyComp, new View({ + template: '{{a.b}}' + })); + + tb.createView(MyComp, {context: ctx}).then((view) => { + expect(() => view.detectChanges()).toThrowError(new RegExp('{{a.b}} in MyComp')); + async.done(); + }) + })); + + it('should specify a location of an error that happened during change detection (element property)', + inject([TestBed, AsyncTestCompleter], (tb, async) => { + + tb.overrideView(MyComp, new View({ + template: '
' + })); + + tb.createView(MyComp, {context: ctx}).then((view) => { + expect(() => view.detectChanges()).toThrowError(new RegExp('a.b in MyComp')); + async.done(); + }) + })); + + it('should specify a location of an error that happened during change detection (directive property)', + inject([TestBed, AsyncTestCompleter], (tb, async) => { + + tb.overrideView(MyComp, new View({ + template: '', + directives: [ChildComp] + })); + + tb.createView(MyComp, {context: ctx}).then((view) => { + expect(() => view.detectChanges()).toThrowError(new RegExp('a.b in MyComp')); + async.done(); + }) + })); }); // Disabled until a solution is found, refs: