Skip to content

Commit

Permalink
Fixes #646
Browse files Browse the repository at this point in the history
  • Loading branch information
zachleat committed Feb 16, 2022
1 parent 9440453 commit b5082b0
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 52 deletions.
26 changes: 16 additions & 10 deletions src/EleventyErrorHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,31 @@ class EleventyErrorHandler {
if (msg) {
this.initialMessage(msg, "error", "red", true);
}
this.log(e, "error", undefined, undefined, true);
this.log(e, "error", undefined, true);
}

//https://nodejs.org/api/process.html
log(e, type = "log", prefix = ">", chalkColor = "", forceToConsole = false) {
log(e, type = "log", chalkColor = "", forceToConsole = false) {
let errorCount = 0;
let errorCountRef = e;
while (errorCountRef) {
errorCount++;
errorCountRef = errorCountRef.originalError;
}

let ref = e;
let index = 1;
while (ref) {
let nextRef = ref.originalError;
if (!nextRef && EleventyErrorUtil.hasEmbeddedError(ref.message)) {
nextRef = EleventyErrorUtil.deconvertErrorToObject(ref);
}

this.logger.message(
(process.env.DEBUG ? "" : `${prefix} `) +
`${(
EleventyErrorUtil.cleanMessage(ref.message) ||
"(No error message provided)"
).trim()}
\`${ref.name}\` was thrown${!nextRef && ref.stack ? ":" : ""}`,
`${errorCount > 1 ? `${index}. ` : ""}${(
EleventyErrorUtil.cleanMessage(ref.message) ||
"(No error message provided)"
).trim()} (via ${ref.name})`,
type,
chalkColor,
forceToConsole
Expand All @@ -85,13 +90,14 @@ class EleventyErrorHandler {
);
}
this.logger.message(
prefix + stackStr.split("\n").join("\n" + prefix),
"\nOriginal error stack trace: " + stackStr,
type,
chalkColor,
forceToConsole
);
}
ref = nextRef;
index++;
}
}

Expand Down
43 changes: 26 additions & 17 deletions src/Template.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ const TemplateLayout = require("./TemplateLayout");
const TemplateFileSlug = require("./TemplateFileSlug");
const ComputedData = require("./ComputedData");
const Pagination = require("./Plugins/Pagination");
const TemplateContentPrematureUseError = require("./Errors/TemplateContentPrematureUseError");
const TemplateContentUnrenderedTemplateError = require("./Errors/TemplateContentUnrenderedTemplateError");
const ConsoleLogger = require("./Util/ConsoleLogger");
const TemplateBehavior = require("./TemplateBehavior");

const TemplateContentPrematureUseError = require("./Errors/TemplateContentPrematureUseError");
const TemplateContentUnrenderedTemplateError = require("./Errors/TemplateContentUnrenderedTemplateError");

const EleventyBaseError = require("./EleventyBaseError");
class EleventyTransformError extends EleventyBaseError {}

const debug = require("debug")("Eleventy:Template");
const debugDev = require("debug")("Dev:Eleventy:Template");

Expand Down Expand Up @@ -54,7 +58,6 @@ class Template extends TemplateContent {

this.linters = [];
this.transforms = [];
this.plugins = {};
this.templateData = templateData;
if (this.templateData) {
this.templateData.setInputDir(this.inputDir);
Expand Down Expand Up @@ -546,21 +549,27 @@ class Template extends TemplateContent {
});
}

// Warning: this argument list is the reverse of linters (inputPath then outputPath)
async runTransforms(str, inputPath, outputPath) {
for (let transform of this.transforms) {
let hadStrBefore = !!str;
str = await transform.callback.call(
{
inputPath,
outputPath,
},
str,
outputPath
);
if (hadStrBefore && !str) {
this.logger.warn(
`Warning: Transform \`${transform.name}\` returned empty when writing ${outputPath} from ${inputPath}.`
for (let { callback, name } of this.transforms) {
try {
let hadStrBefore = !!str;
str = await callback.call(
{
inputPath,
outputPath,
},
str,
outputPath
);
if (hadStrBefore && !str) {
this.logger.warn(
`Warning: Transform \`${name}\` returned empty when writing ${outputPath} from ${inputPath}.`
);
}
} catch (e) {
throw new EleventyTransformError(
`Transform \`${name}\` encountered an error when transforming ${inputPath}.`,
e
);
}
}
Expand Down
31 changes: 27 additions & 4 deletions src/TemplateConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ const deleteRequireCache = require("./Util/DeleteRequireCache");
*/
class EleventyConfigError extends EleventyBaseError {}

/**
* Errors in eleventy plugins.
*/
class EleventyPluginError extends EleventyBaseError {}

/**
* Config for a template.
*
Expand Down Expand Up @@ -181,11 +186,29 @@ class TemplateConfig {
this.userConfig._enablePluginExecution();

let storedActiveNamespace = this.userConfig.activeNamespace;
for (let { plugin, options, pluginNamespace } of this.userConfig.plugins) {
try {
this.userConfig.activeNamespace = pluginNamespace;
this.userConfig._executePlugin(plugin, options);
} catch (e) {
let name = this.userConfig._getPluginName(plugin);
let namespaces = [storedActiveNamespace, pluginNamespace].filter(
(entry) => !!entry
);

this.userConfig.plugins.forEach(({ plugin, options, pluginNamespace }) => {
this.userConfig.activeNamespace = pluginNamespace;
this.userConfig._executePlugin(plugin, options);
});
let namespaceStr = "";
if (namespaces.length) {
namespaceStr = ` (namespace: ${namespaces.join(".")})`;
}

throw new EleventyPluginError(
`Error processing ${
name ? `the \`${name}\`` : "a"
} plugin${namespaceStr}`,
e
);
}
}

this.userConfig.activeNamespace = storedActiveNamespace;
}
Expand Down
17 changes: 9 additions & 8 deletions src/TemplateWriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ const ConsoleLogger = require("./Util/ConsoleLogger");
const debug = require("debug")("Eleventy:TemplateWriter");
const debugDev = require("debug")("Dev:Eleventy:TemplateWriter");

class TemplateWriterError extends EleventyBaseError {}
class TemplateWriterWriteError extends EleventyBaseError {}
class TemplateWriterMissingConfigArgError extends EleventyBaseError {}
class EleventyPassthroughCopyError extends EleventyBaseError {}
class EleventyTemplateError extends EleventyBaseError {}

class TemplateWriter {
constructor(
Expand All @@ -23,7 +24,7 @@ class TemplateWriter {
eleventyConfig
) {
if (!eleventyConfig) {
throw new TemplateWriterError("Missing config argument.");
throw new TemplateWriterMissingConfigArgError("Missing config argument.");
}
this.eleventyConfig = eleventyConfig;
this.config = eleventyConfig.getConfig();
Expand Down Expand Up @@ -262,7 +263,7 @@ class TemplateWriter {
return passthroughManager.copyAll(paths).catch((e) => {
this.errorHandler.warn(e, "Error with passthrough copy");
return Promise.reject(
new TemplateWriterWriteError("Having trouble copying", e)
new EleventyPassthroughCopyError("Having trouble copying", e)
);
});
}
Expand All @@ -286,8 +287,8 @@ class TemplateWriter {
usedTemplateContentTooEarlyMap.push(mapEntry);
} else {
return Promise.reject(
new TemplateWriterWriteError(
`Having trouble writing template: ${mapEntry.outputPath}`,
new EleventyTemplateError(
`Having trouble writing template: "${mapEntry.outputPath}"`,
e
)
);
Expand All @@ -300,8 +301,8 @@ class TemplateWriter {
promises.push(
this._generateTemplate(mapEntry, to).catch(function (e) {
return Promise.reject(
new TemplateWriterWriteError(
`Having trouble writing template (second pass): ${mapEntry.outputPath}`,
new EleventyTemplateError(
`Having trouble writing template (second pass): "${mapEntry.outputPath}"`,
e
)
);
Expand Down
15 changes: 14 additions & 1 deletion src/UserConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,21 @@ class UserConfig {
}
}

// Using Function.name https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#examples
_getPluginName(plugin) {
if (typeof plugin === "function") {
return plugin.name;
} else if (
plugin.configFunction &&
typeof plugin.configFunction === "function"
) {
return plugin.configFunction.name;
}
}

_executePlugin(plugin, options) {
debug(`Adding ${plugin.name || "anonymous"} plugin`);
let name = this._getPluginName(plugin);
debug(`Adding ${name || "anonymous"} plugin`);
let pluginBenchmark = this.benchmarks.aggregate.get(
"Configuration addPlugin"
);
Expand Down
2 changes: 1 addition & 1 deletion src/Util/ConsoleLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ConsoleLogger {
if (!forceToConsole && (!this.isVerbose || process.env.DEBUG)) {
debug(message);
} else if (this._logger !== false) {
message = `[11ty] ${message}`;
message = `[11ty] ${message.split("\n").join("\n[11ty] ")}`;

let logger = this._logger || console;
if (chalkColor && this.isChalkEnabled) {
Expand Down
34 changes: 23 additions & 11 deletions test/EleventyErrorHandlerTest.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const test = require("ava");
const EleventyErrorHandler = require("../src/EleventyErrorHandler");

test("Log a warning, error", (t) => {
test("Log a warning, warning", (t) => {
let errorHandler = new EleventyErrorHandler();
let output = [];
errorHandler.logger = {
Expand All @@ -18,24 +18,36 @@ test("Log a warning, error", (t) => {
output.push(str);
},
};

errorHandler.warn(new Error("Test warning"), "Hello");

let expected = `Hello: (more in DEBUG output)
> Test warning
\`Error\` was thrown:
Error: Test warning`;
let expected = "Hello: (more in DEBUG output)";
t.is(output.join("\n").substr(0, expected.length), expected);
});

output = [];
test("Log a warning, error", (t) => {
let errorHandler = new EleventyErrorHandler();

let output = [];
errorHandler.logger = {
log: function (str) {
output.push(str);
},
warn: function (str) {
output.push(str);
},
error: function (str) {
output.push(str);
},
message: function (str) {
output.push(str);
},
};

errorHandler.error(new Error("Test error"), "It’s me");

expected = `It’s me: (more in DEBUG output)
> Test error
Test error (via Error)
\`Error\` was thrown:
Error: Test error`;
Original error stack trace: Error: Test error`;
t.is(output.join("\n").substr(0, expected.length), expected);
});

0 comments on commit b5082b0

Please sign in to comment.