Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit d804bbc

Browse files
btfordIgorMinar
authored andcommitted
feat($interpolate): provide contextual error messages
if an exception occurs during interpolation of a string (e.g. name() in "Hello, {{name()}}!" throws an exception) we now print an error message with the expression that was being evaluated when the exception was thrown.
1 parent d3fa7a2 commit d804bbc

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

src/ng/interpolate.js

+16-10
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function $InterpolateProvider() {
5252
};
5353

5454

55-
this.$get = ['$parse', function($parse) {
55+
this.$get = ['$parse', '$exceptionHandler', function($parse, $exceptionHandler) {
5656
var startSymbolLength = startSymbol.length,
5757
endSymbolLength = endSymbol.length;
5858

@@ -124,18 +124,24 @@ function $InterpolateProvider() {
124124
if (!mustHaveExpression || hasInterpolation) {
125125
concat.length = length;
126126
fn = function(context) {
127-
for(var i = 0, ii = length, part; i<ii; i++) {
128-
if (typeof (part = parts[i]) == 'function') {
129-
part = part(context);
130-
if (part == null || part == undefined) {
131-
part = '';
132-
} else if (typeof part != 'string') {
133-
part = toJson(part);
127+
try {
128+
for(var i = 0, ii = length, part; i<ii; i++) {
129+
if (typeof (part = parts[i]) == 'function') {
130+
part = part(context);
131+
if (part == null || part == undefined) {
132+
part = '';
133+
} else if (typeof part != 'string') {
134+
part = toJson(part);
135+
}
134136
}
137+
concat[i] = part;
135138
}
136-
concat[i] = part;
139+
return concat.join('');
140+
}
141+
catch(err) {
142+
var newErr = new Error('Error while interpolating: ' + text + '\n' + err.toString());
143+
$exceptionHandler(newErr);
137144
}
138-
return concat.join('');
139145
};
140146
fn.exp = text;
141147
fn.parts = parts;

test/BinderSpec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ describe('Binder', function() {
175175
$rootScope.error['throw'] = function() {throw 'MyError';};
176176
errorLogs.length = 0;
177177
$rootScope.$apply();
178-
expect(errorLogs.shift()).toBe('MyError');
178+
expect(errorLogs.shift().message).toBe('Error while interpolating: {{error.throw()}}\nMyError');
179179

180180
$rootScope.error['throw'] = function() {return 'ok';};
181181
$rootScope.$apply();

test/ng/interpolateSpec.js

+23
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ describe('$interpolate', function() {
2525
expect($interpolate('{{ false }}')()).toEqual('false');
2626
}));
2727

28+
it('should rethrow exceptions', inject(function($interpolate, $rootScope) {
29+
$rootScope.err = function () {
30+
throw new Error('oops');
31+
};
32+
expect(function () {
33+
$interpolate('{{err()}}')($rootScope);
34+
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
35+
}));
36+
37+
it('should stop interpolation when encountering an exception', inject(function($interpolate, $compile, $rootScope) {
38+
$rootScope.err = function () {
39+
throw new Error('oops');
40+
};
41+
var dom = jqLite('<div>{{1 + 1}}</div><div>{{err()}}</div><div>{{1 + 2}}</div>');
42+
$compile(dom)($rootScope);
43+
expect(function () {
44+
$rootScope.$apply();
45+
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
46+
expect(dom[0].innerHTML).toEqual('2');
47+
expect(dom[1].innerHTML).toEqual('{{err()}}');
48+
expect(dom[2].innerHTML).toEqual('{{1 + 2}}');
49+
}));
50+
2851

2952
it('should return interpolation function', inject(function($interpolate, $rootScope) {
3053
$rootScope.name = 'Misko';

0 commit comments

Comments
 (0)