template-error
Version:
Make template errors easy to understand and fix.
72 lines (61 loc) • 1.59 kB
JavaScript
;
var fs = require('fs');
var lazy = require('lazy-cache')(require);
lazy('kind-of', 'typeOf');
lazy('rethrow');
lazy('engine');
function error(str, options) {
options = options || {};
var fp = options.fp || 'string';
var data = options.data || {};
var re = options.regex || /<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|\$\{([^\\}]*(?:\\.[^\\}]*)*)\}|<%([\s\S]+?)%>|$/g;
var regex = toRegexp(re);
str.replace(regex, function(match, prop, i) {
try {
var engine = lazy.engine();
engine.render(str, data);
} catch (err) {
var rethrow = lazy.rethrow({});
var prop = matchProp(err.message);
var match = findProp(prop, str, regex);
var before = str.slice(0, match.index);
var lineno = before.split('\n').length;
rethrow(err, fp, lineno, str);
}
});
};
function matchProp(str) {
var re = /(\w+) is not defined/;
var m = re.exec(str);
if (!m) return;
return m[1];
}
function findProp(prop, str, re) {
var src = re.source;
var left = /^([-{<\[=%]+)/.exec(src);
var esc = '(?:[' + left[0].split('').join('\\') + '\\s]+)';
var delim = esc + '.*' + prop;
var re = new RegExp(delim, 'm');
return re.exec(str);
}
function toRegexp(val) {
if (lazy.typeOf(val) === 'regexp') {
return val;
}
if (lazy.typeOf(val) === 'object') {
return val.interpolate;
}
}
function toSettings(val) {
if (lazy.typeOf(val) === 'regexp') {
return { interpolate: val };
}
if (lazy.typeOf(val) === 'object') {
return val;
}
return null;
}
/**
* Expose `error`
*/
module.exports = error;