diff --git a/lib/handlebars.js b/lib/handlebars.js index 9b5ce0c6..80e1de0b 100644 --- a/lib/handlebars.js +++ b/lib/handlebars.js @@ -2,7 +2,7 @@ Handlebars = { compile: function(string) { var compiler = new Handlebars.Compiler(string); var result = compiler.compile(); - return new Function("context", "fallback", "fallback = fallback || {}; var stack = [];var partials = {};" + result); + return new Function("context", "fallback", "fallback = fallback || {}; var stack = [];" + result); }, isFunction: function(fn) { @@ -90,7 +90,7 @@ Handlebars = { switch(parts[i]) { case "..": if (readDepth) { - throw new Handlebars.ParseError("Cannot jump out of context after moving into a context."); + throw new Handlebars.Exception("Cannot jump out of context after moving into a context."); } else { depth += 1; } @@ -122,7 +122,7 @@ Handlebars.Compiler = function(string) { this.partial = false; }; -Handlebars.ParseError = function(message) { +Handlebars.Exception = function(message) { this.message = message; }; @@ -252,8 +252,9 @@ Handlebars.Compiler.prototype = { addPartial: function(mustache, param) { // either used a cached copy of the partial or compile a new one - this.fn += "if (typeof partials['" + mustache + "'] === 'undefined') partials['" + mustache + "'] = Handlebars.compile(fallback['partials']['" + mustache + "']);"; - this.fn += "out = out + partials['" + mustache + "'](" + param + ", fallback);"; + this.fn += "if (typeof fallback['partials'] === 'undefined' || typeof fallback['partials']['" + mustache + "'] === 'undefined') throw new Handlebars.Exception('Attempted to render undefined partial: " + mustache + "');"; + this.fn += "if (!Handlebars.isFunction(fallback['partials']['" + mustache + "'])) fallback['partials']['" + mustache + "'] = Handlebars.compile(fallback['partials']['" + mustache + "']);"; + this.fn += "out = out + fallback['partials']['" + mustache + "'](" + param + ", fallback);"; }, parseMustache: function() { diff --git a/test/handlebars.js b/test/handlebars.js index a394f3b9..36421004 100644 --- a/test/handlebars.js +++ b/test/handlebars.js @@ -64,7 +64,7 @@ test("bad idea nested paths", function() { try { Handlebars.compile("{{#goodbyes}}{{../name/../name}}{{/goodbyes}}"); } catch (e) { - if (e instanceof Handlebars.ParseError) { + if (e instanceof Handlebars.Exception) { caught = true; } } @@ -211,6 +211,19 @@ test("partial in a partial", function() { shouldCompileTo(string, [hash, {partials: {dude: dude, url: url}}], "Dudes: Yehuda http://yehuda Alan http://alan ", "Partials are rendered inside of other partials"); }); +test("rendering undefined partial throws an exception", function() { + var caught = false; + try { + var template = Handlebars.compile("{{> whatever}}"); + template(); + } catch (e) { + if (e instanceof Handlebars.Exception) { + caught = true; + } + } + equals(caught, true); +}); + module("safestring"); test("constructing a safestring from a string and checking its type", function() {