Skip to content

Commit

Permalink
Merge pull request #237 from ember-fastboot/better-error-message
Browse files Browse the repository at this point in the history
Better `ember fastboot` error message
  • Loading branch information
tomdale committed Jul 29, 2016
2 parents 32d40b2 + 1ed9c2f commit ec22f4d
Showing 1 changed file with 55 additions and 2 deletions.
57 changes: 55 additions & 2 deletions lib/tasks/fastboot-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ module.exports = CoreObject.extend({
this.restartPromise = this.stop()
.then(() => this.clearRequireCache(options.outputPath))
.then(() => this.start(options))
.catch(e => this.ui.writeLine(e))
.catch(e => this.printError(e))
.finally(() => {
this.restartPromise = null;
if (this.restartAgain) {
debug('restart again')
debug('restart again');
this.restartAgain = false;
this.restart(options);
}
Expand All @@ -120,5 +120,58 @@ module.exports = CoreObject.extend({
delete require.cache[key];
}
});
},

/*
* Try to show a useful error message if we're not able to start the user's
* app in FastBoot.
*/
printError: function(e) {
var preamble = ["There was an error trying to run your application in FastBoot.\n",
"This is usually caused by either your application code or an addon trying to access " +
"an API that isn't available in Node.js."];

// If there's a stack trace available, try to extract some information for
// it so we can generate a more helpful error message.
if (e.stack) {
// Look at the stack trace line by line
var stack = e.stack.split('\n');

// Verify there's a second line with path information.
// (First line is the error message itself.)
if (stack[1]) {
// Extract path and line number information. An example line looks like either:
// at /Users/monegraph/Code/fastboot-test/dist/fastboot/vendor.js:65045:19
// or
// at Module.callback (/Users/monegraph/Code/fastboot test/dist/fastboot/fastboot-test.js:23:31)
var match = stack[1].match(/\s*(?:at .* \(([^:]+):(\d+):(\d+)|at ([^:]+):(\d+):(\d+)$)/);
if (match) {
var fileName = match[1] || match[4];
var lineNumber = match[2] || match[5];

// Print file name and line number from the top of the stack. This is displayed
// anyway, of course, but not everyone knows how to read a stack trace. This makes
// it more obvious.
var badFilePath = path.relative(process.cwd(), fileName);
preamble.push("Based on the stack trace, it looks like the exception was generated in " + badFilePath + " on line " + lineNumber + ".");

// If the exception is coming from `vendor.js`, that usually means it's from an addon and thus may be
// out of the user's control. Give the user some instructions so they can try to figure out which
// addon is causing the problem.
if (fileName.substr(-9) === 'vendor.js') {
preamble.push("Because it's coming from vendor.js, an addon is most likely responsible for this error. You should look at this " +
"file and line number to determine which addon is not yet FastBoot compatible.");

} else {
preamble.push("The exception is probably coming from your app. Look at this file and line number to determine what is triggering the exception.");
}
}
}

preamble.push("\nThe full stack trace is:");
}

this.ui.writeError(preamble.join('\n') + '\n');
this.ui.writeError(e);
}
});

0 comments on commit ec22f4d

Please sign in to comment.