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

Commit

Permalink
feat($interpolate): provide contextual error messages
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
btford authored and IgorMinar committed Aug 30, 2012
1 parent d3fa7a2 commit d804bbc
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
26 changes: 16 additions & 10 deletions src/ng/interpolate.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function $InterpolateProvider() {
};


this.$get = ['$parse', function($parse) {
this.$get = ['$parse', '$exceptionHandler', function($parse, $exceptionHandler) {
var startSymbolLength = startSymbol.length,
endSymbolLength = endSymbol.length;

Expand Down Expand Up @@ -124,18 +124,24 @@ function $InterpolateProvider() {
if (!mustHaveExpression || hasInterpolation) {
concat.length = length;
fn = function(context) {
for(var i = 0, ii = length, part; i<ii; i++) {
if (typeof (part = parts[i]) == 'function') {
part = part(context);
if (part == null || part == undefined) {
part = '';
} else if (typeof part != 'string') {
part = toJson(part);
try {
for(var i = 0, ii = length, part; i<ii; i++) {
if (typeof (part = parts[i]) == 'function') {
part = part(context);
if (part == null || part == undefined) {
part = '';
} else if (typeof part != 'string') {
part = toJson(part);
}
}
concat[i] = part;
}
concat[i] = part;
return concat.join('');
}
catch(err) {
var newErr = new Error('Error while interpolating: ' + text + '\n' + err.toString());
$exceptionHandler(newErr);
}
return concat.join('');
};
fn.exp = text;
fn.parts = parts;
Expand Down
2 changes: 1 addition & 1 deletion test/BinderSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ describe('Binder', function() {
$rootScope.error['throw'] = function() {throw 'MyError';};
errorLogs.length = 0;
$rootScope.$apply();
expect(errorLogs.shift()).toBe('MyError');
expect(errorLogs.shift().message).toBe('Error while interpolating: {{error.throw()}}\nMyError');

$rootScope.error['throw'] = function() {return 'ok';};
$rootScope.$apply();
Expand Down
23 changes: 23 additions & 0 deletions test/ng/interpolateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,29 @@ describe('$interpolate', function() {
expect($interpolate('{{ false }}')()).toEqual('false');
}));

it('should rethrow exceptions', inject(function($interpolate, $rootScope) {
$rootScope.err = function () {
throw new Error('oops');
};
expect(function () {
$interpolate('{{err()}}')($rootScope);
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
}));

it('should stop interpolation when encountering an exception', inject(function($interpolate, $compile, $rootScope) {
$rootScope.err = function () {
throw new Error('oops');
};
var dom = jqLite('<div>{{1 + 1}}</div><div>{{err()}}</div><div>{{1 + 2}}</div>');
$compile(dom)($rootScope);
expect(function () {
$rootScope.$apply();
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
expect(dom[0].innerHTML).toEqual('2');
expect(dom[1].innerHTML).toEqual('{{err()}}');
expect(dom[2].innerHTML).toEqual('{{1 + 2}}');
}));


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

0 comments on commit d804bbc

Please sign in to comment.