From feb60f85c90826369672cf93bf97343f0e246717 Mon Sep 17 00:00:00 2001 From: sohibe Date: Wed, 29 May 2019 03:39:03 +0300 Subject: [PATCH] show source location for the strict lookup exceptions --- .../compiler/javascript-compiler.js | 3 ++- lib/handlebars/exception.js | 15 +++++++++++++-- lib/handlebars/runtime.js | 6 +++--- spec/strict.js | 19 +++++++++++++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index dec107e8b..cc26eb240 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -1091,6 +1091,7 @@ JavaScriptCompiler.prototype = { setupHelperArgs: function(helper, paramSize, params, useRegister) { let options = this.setupParams(helper, paramSize, params); + options.loc = JSON.stringify(this.source.currentLocation); options = this.objectLiteral(options); if (useRegister) { this.useRegister('options'); @@ -1150,7 +1151,7 @@ function strictLookup(requireTerminal, compiler, parts, type) { } if (requireTerminal) { - return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')']; + return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ', ', JSON.stringify(compiler.source.currentLocation), ' )']; } else { return stack; } diff --git a/lib/handlebars/exception.js b/lib/handlebars/exception.js index b9a5557b6..6333f1907 100644 --- a/lib/handlebars/exception.js +++ b/lib/handlebars/exception.js @@ -1,13 +1,18 @@ -const errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; +const errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack']; function Exception(message, node) { let loc = node && node.loc, line, - column; + endLineNumber, + column, + endColumn; + if (loc) { line = loc.start.line; + endLineNumber = loc.end.line; column = loc.start.column; + endColumn = loc.end.column; message += ' - ' + line + ':' + column; } @@ -27,6 +32,7 @@ function Exception(message, node) { try { if (loc) { this.lineNumber = line; + this.endLineNumber = endLineNumber; // Work around issue under safari where we can't directly set the column value /* istanbul ignore next */ @@ -35,8 +41,13 @@ function Exception(message, node) { value: column, enumerable: true }); + Object.defineProperty(this, 'endColumn', { + value: endColumn, + enumerable: true + }); } else { this.column = column; + this.endColumn = endColumn; } } } catch (nop) { diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index 763016de7..958afc3ef 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -79,9 +79,9 @@ export function template(templateSpec, env) { // Just add water let container = { - strict: function(obj, name) { - if (!(name in obj)) { - throw new Exception('"' + name + '" not defined in ' + obj); + strict: function(obj, name, loc) { + if (!obj || !(name in obj)) { + throw new Exception('"' + name + '" not defined in ' + obj, { loc: loc }); } return obj[name]; }, diff --git a/spec/strict.js b/spec/strict.js index 05ce35d9e..3bd7cc18e 100644 --- a/spec/strict.js +++ b/spec/strict.js @@ -95,6 +95,25 @@ describe('strict', function() { }; equals(template({}, {helpers: helpers}), 'success'); }); + + it('should show error location on missing property lookup', function() { + shouldThrow(function() { + var template = CompilerContext.compile('\n\n\n {{hello}}', {strict: true}); + template({}); + }, Exception, '"hello" not defined in [object Object] - 4:5'); + }); + + it('should error contains correct location properties on missing property lookup', function() { + try { + var template = CompilerContext.compile('\n\n\n {{hello}}', {strict: true}); + template({}); + } catch (error) { + equals(error.lineNumber, 4); + equals(error.endLineNumber, 4); + equals(error.column, 5); + equals(error.endColumn, 10); + } + }); }); describe('assume objects', function() {