Skip to content

Commit

Permalink
Cleanup error location and origin information
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jun 4, 2018
1 parent 53f7deb commit 53103a9
Show file tree
Hide file tree
Showing 28 changed files with 191 additions and 169 deletions.
8 changes: 4 additions & 4 deletions lib/AsyncDependencyToInitialChunkError.js
Expand Up @@ -16,13 +16,13 @@ class AsyncDependencyToInitialChunkError extends WebpackError {
* @param {TODO} loc location of dependency
*/
constructor(chunkName, module, loc) {
super();
super(
`It's not allowed to load an initial chunk on demand. The chunk name "${chunkName}" is already used by an entrypoint.`
);

this.name = "AsyncDependencyToInitialChunkError";
this.message = `It's not allowed to load an initial chunk on demand. The chunk name "${chunkName}" is already used by an entrypoint.`;
this.module = module;
this.origin = module;
this.originLoc = loc;
this.loc = loc;

Error.captureStackTrace(this, this.constructor);
}
Expand Down
86 changes: 41 additions & 45 deletions lib/CaseSensitiveModulesWarning.js
Expand Up @@ -8,64 +8,60 @@ const WebpackError = require("./WebpackError");

/** @typedef {import("./Module")} Module */

/**
* @param {Module[]} modules the modules to be sorted
* @returns {Module[]} sorted version of original modules
*/
const sortModules = modules => {
return modules.slice().sort((a, b) => {
a = a.identifier();
b = b.identifier();
/* istanbul ignore next */
if (a < b) return -1;
/* istanbul ignore next */
if (a > b) return 1;
/* istanbul ignore next */
return 0;
});
};

/**
* @param {Module[]} modules each module from throw
* @returns {string} each message from provided moduels
*/
const createModulesListMessage = modules => {
return modules
.map(m => {
let message = `* ${m.identifier()}`;
const validReasons = m.reasons.filter(reason => reason.module);

if (validReasons.length > 0) {
message += `\n Used by ${validReasons.length} module(s), i. e.`;
message += `\n ${validReasons[0].module.identifier()}`;
}
return message;
})
.join("\n");
};

class CaseSensitiveModulesWarning extends WebpackError {
/**
* Creates an instance of CaseSensitiveModulesWarning.
* @param {Module[]} modules modules that were detected
*/
constructor(modules) {
super();

this.name = "CaseSensitiveModulesWarning";
const sortedModules = this._sort(modules);
const modulesList = this._moduleMessages(sortedModules);
this.message = `There are multiple modules with names that only differ in casing.
const sortedModules = sortModules(modules);
const modulesList = createModulesListMessage(sortedModules);
super(`There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
${modulesList}`;
${modulesList}`);

this.name = "CaseSensitiveModulesWarning";
this.origin = this.module = sortedModules[0];

Error.captureStackTrace(this, this.constructor);
}

/**
* @private
* @param {Module[]} modules the modules to be sorted
* @returns {Module[]} sorted version of original modules
*/
_sort(modules) {
return modules.slice().sort((a, b) => {
a = a.identifier();
b = b.identifier();
/* istanbul ignore next */
if (a < b) return -1;
/* istanbul ignore next */
if (a > b) return 1;
/* istanbul ignore next */
return 0;
});
}

/**
* @private
* @param {Module[]} modules each module from throw
* @returns {string} each message from provided moduels
*/
_moduleMessages(modules) {
return modules
.map(m => {
let message = `* ${m.identifier()}`;
const validReasons = m.reasons.filter(reason => reason.module);

if (validReasons.length > 0) {
message += `\n Used by ${validReasons.length} module(s), i. e.`;
message += `\n ${validReasons[0].module.identifier()}`;
}
return message;
})
.join("\n");
}
}

module.exports = CaseSensitiveModulesWarning;
3 changes: 2 additions & 1 deletion lib/Compilation.js
Expand Up @@ -487,6 +487,7 @@ class Compilation extends Tapable {

const errorAndCallback = err => {
err.origin = module;
err.dependencies = dependencies;
this.errors.push(err);
if (bail) {
callback(err);
Expand Down Expand Up @@ -531,7 +532,7 @@ class Compilation extends Tapable {
if (err) {
semaphore.release();
return errorOrWarningAndCallback(
new ModuleNotFoundError(module, err, dependencies)
new ModuleNotFoundError(module, err)
);
}
if (!dependentModule) {
Expand Down
3 changes: 1 addition & 2 deletions lib/EntryModuleNotFoundError.js
Expand Up @@ -8,10 +8,9 @@ const WebpackError = require("./WebpackError");

class EntryModuleNotFoundError extends WebpackError {
constructor(err) {
super();
super("Entry module not found: " + err);

this.name = "EntryModuleNotFoundError";
this.message = "Entry module not found: " + err;
this.details = err.details;
this.error = err;

Expand Down
3 changes: 1 addition & 2 deletions lib/HarmonyLinkingError.js
Expand Up @@ -8,9 +8,8 @@ const WebpackError = require("./WebpackError");
module.exports = class HarmonyLinkingError extends WebpackError {
/** @param {string} message Error message */
constructor(message) {
super();
super(message);
this.name = "HarmonyLinkingError";
this.message = message;
this.hideStack = true;

Error.captureStackTrace(this, this.constructor);
Expand Down
23 changes: 13 additions & 10 deletions lib/ModuleBuildError.js
Expand Up @@ -9,29 +9,32 @@ const { cutOffLoaderExecution } = require("./ErrorHelpers");

class ModuleBuildError extends WebpackError {
constructor(module, err) {
super();

this.name = "ModuleBuildError";
this.message = "Module build failed: ";
let message = "Module build failed: ";
let details = undefined;
if (err !== null && typeof err === "object") {
if (typeof err.stack === "string" && err.stack) {
var stack = cutOffLoaderExecution(err.stack);
if (!err.hideStack) {
this.message += stack;
message += stack;
} else {
this.details = stack;
details = stack;
if (typeof err.message === "string" && err.message) {
this.message += err.message;
message += err.message;
} else {
this.message += err;
message += err;
}
}
} else if (typeof err.message === "string" && err.message) {
this.message += err.message;
message += err.message;
} else {
this.message += err;
message += err;
}
}

super(message);

this.name = "ModuleBuildError";
this.details = details;
this.module = module;
this.error = err;

Expand Down
7 changes: 3 additions & 4 deletions lib/ModuleDependencyError.js
Expand Up @@ -5,7 +5,6 @@
"use strict";

const WebpackError = require("./WebpackError");
const formatLocation = require("./formatLocation");

/** @typedef {import("./Module")} Module */

Expand All @@ -17,15 +16,15 @@ class ModuleDependencyError extends WebpackError {
* @param {TODO} loc location of dependency
*/
constructor(module, err, loc) {
super();
super(err.message);

this.name = "ModuleDependencyError";
this.message = `${formatLocation(loc)} ${err.message}`;
this.details = err.stack
.split("\n")
.slice(1)
.join("\n");
this.origin = this.module = module;
this.module = module;
this.loc = loc;
this.error = err;

Error.captureStackTrace(this, this.constructor);
Expand Down
7 changes: 3 additions & 4 deletions lib/ModuleDependencyWarning.js
Expand Up @@ -5,19 +5,18 @@
"use strict";

const WebpackError = require("./WebpackError");
const formatLocation = require("./formatLocation");

module.exports = class ModuleDependencyWarning extends WebpackError {
constructor(module, err, loc) {
super();
super(err.message);

this.name = "ModuleDependencyWarning";
this.message = `${formatLocation(loc)} ${err.message}`;
this.details = err.stack
.split("\n")
.slice(1)
.join("\n");
this.origin = this.module = module;
this.module = module;
this.loc = loc;
this.error = err;

Error.captureStackTrace(this, this.constructor);
Expand Down
4 changes: 1 addition & 3 deletions lib/ModuleError.js
Expand Up @@ -9,12 +9,10 @@ const { cleanUp } = require("./ErrorHelpers");

class ModuleError extends WebpackError {
constructor(module, err) {
super();
super(err && typeof err === "object" && err.message ? err.message : err);

this.name = "ModuleError";
this.module = module;
this.message =
err && typeof err === "object" && err.message ? err.message : err;
this.error = err;
this.details =
err && typeof err === "object" && err.stack
Expand Down
7 changes: 2 additions & 5 deletions lib/ModuleNotFoundError.js
Expand Up @@ -7,16 +7,13 @@
const WebpackError = require("./WebpackError");

class ModuleNotFoundError extends WebpackError {
constructor(module, err, dependencies) {
super();
constructor(module, err) {
super("Module not found: " + err);

this.name = "ModuleNotFoundError";
this.message = "Module not found: " + err;
this.details = err.details;
this.missing = err.missing;
this.module = module;
this.origin = module;
this.dependencies = dependencies;
this.error = err;

Error.captureStackTrace(this, this.constructor);
Expand Down
41 changes: 27 additions & 14 deletions lib/ModuleParseError.js
Expand Up @@ -6,14 +6,18 @@

const WebpackError = require("./WebpackError");

/** @typedef {import("./Module")} Module */

class ModuleParseError extends WebpackError {
/**
* @param {Module} module the errored module
* @param {string} source source code
* @param {Error&any} err the parse error
*/
constructor(module, source, err) {
super();

this.name = "ModuleParseError";
this.message = "Module parse failed: " + err.message;
this.message +=
"\nYou may need an appropriate loader to handle this file type.";
let message = "Module parse failed: " + err.message;
let loc = undefined;
message += "\nYou may need an appropriate loader to handle this file type.";
if (
err.loc &&
typeof err.loc === "object" &&
Expand All @@ -22,19 +26,28 @@ class ModuleParseError extends WebpackError {
var lineNumber = err.loc.line;
if (/[\0\u0001\u0002\u0003\u0004\u0005\u0006\u0007]/.test(source)) {
// binary file
this.message += "\n(Source code omitted for this binary file)";
message += "\n(Source code omitted for this binary file)";
} else {
source = source.split("\n");
this.message +=
"\n| " +
source
.slice(Math.max(0, lineNumber - 3), lineNumber + 2)
.join("\n| ");
const sourceLines = source.split("\n");
const start = Math.max(0, lineNumber - 3);
const linesBefore = sourceLines.slice(start, lineNumber - 1);
const theLine = sourceLines[lineNumber - 1];
const linesAfter = sourceLines.slice(lineNumber, lineNumber + 2);
message +=
linesBefore.map(l => `\n| ${l}`).join("") +
`\n> ${theLine}` +
linesAfter.map(l => `\n| ${l}`).join("");
}
loc = err.loc;
} else {
this.message += "\n" + err.stack;
message += "\n" + err.stack;
}

super(message);

this.name = "ModuleParseError";
this.module = module;
this.loc = loc;
this.error = err;

Error.captureStackTrace(this, this.constructor);
Expand Down
10 changes: 5 additions & 5 deletions lib/ModuleWarning.js
Expand Up @@ -9,14 +9,14 @@ const { cleanUp } = require("./ErrorHelpers");

class ModuleWarning extends WebpackError {
constructor(module, warning) {
super();
super(
warning && typeof warning === "object" && warning.message
? warning.message
: warning
);

this.name = "ModuleWarning";
this.module = module;
this.message =
warning && typeof warning === "object" && warning.message
? warning.message
: warning;
this.warning = warning;
this.details =
warning && typeof warning === "object" && warning.stack
Expand Down
2 changes: 1 addition & 1 deletion lib/ParserHelpers.js
Expand Up @@ -88,7 +88,7 @@ ParserHelpers.expressionIsUnsupported = (parser, message) => {
parser.state.current.addDependency(dep);
if (!parser.state.module) return;
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(parser.state.module, message)
new UnsupportedFeatureWarning(parser.state.module, message, expr.loc)
);
return true;
};
Expand Down
4 changes: 1 addition & 3 deletions lib/RemovedPluginError.js
Expand Up @@ -4,9 +4,7 @@ const WebpackError = require("./WebpackError");

module.exports = class RemovedPluginError extends WebpackError {
constructor(message) {
super();

this.message = message;
super(message);

Error.captureStackTrace(this, this.constructor);
}
Expand Down

0 comments on commit 53103a9

Please sign in to comment.