Avoid using a getter for the compiler error's "stack" property

Instead, set the "stack" property manually when the error gets updated on re-throws.
This commit is contained in:
Demian Ferreiro 2013-08-02 01:52:36 -03:00
parent 2b4a37296f
commit 9e716b310d
7 changed files with 35 additions and 31 deletions

View File

@ -36,9 +36,7 @@
return fn.call(this, code, options);
} catch (_error) {
err = _error;
err.code || (err.code = code);
err.filename || (err.filename = options.filename);
throw err;
throw helpers.updateSyntaxError(err, code, options.filename);
}
};
};
@ -192,9 +190,7 @@
});
} catch (_error) {
err = _error;
err.filename || (err.filename = filename);
err.code || (err.code = stripped);
throw err;
throw helpers.updateSyntaxError(err, stripped, filename);
}
return answer;
};

View File

@ -191,16 +191,19 @@
error = new SyntaxError(message);
error.location = location;
error.toString = syntaxErrorToString;
if (typeof Object.defineProperty === "function") {
Object.defineProperty(error, 'stack', {
get: function() {
return this.toString();
}
});
}
error.stack = error.toString();
throw error;
};
exports.updateSyntaxError = function(error, code, filename) {
if (error.toString === syntaxErrorToString) {
error.code || (error.code = code);
error.filename || (error.filename = filename);
error.stack = error.toString();
}
return error;
};
syntaxErrorToString = function() {
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, start, _ref1, _ref2;
if (!(this.code && this.location)) {

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.3
(function() {
var CoffeeScript, addHistory, addMultilineHandler, fs, merge, nodeREPL, path, replDefaults, vm;
var CoffeeScript, addHistory, addMultilineHandler, fs, merge, nodeREPL, path, replDefaults, updateSyntaxError, vm, _ref;
fs = require('fs');
@ -12,17 +12,17 @@
CoffeeScript = require('./coffee-script');
merge = require('./helpers').merge;
_ref = require('./helpers'), merge = _ref.merge, updateSyntaxError = _ref.updateSyntaxError;
replDefaults = {
prompt: 'coffee> ',
historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0,
historyMaxInputSize: 10240,
"eval": function(input, context, filename, cb) {
var Assign, Block, Literal, Value, ast, err, js, _ref;
var Assign, Block, Literal, Value, ast, err, js, _ref1;
input = input.replace(/\uFF00/g, '\n');
input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1');
_ref = require('./nodes'), Block = _ref.Block, Assign = _ref.Assign, Value = _ref.Value, Literal = _ref.Literal;
_ref1 = require('./nodes'), Block = _ref1.Block, Assign = _ref1.Assign, Value = _ref1.Value, Literal = _ref1.Literal;
try {
ast = CoffeeScript.nodes(input);
ast = new Block([new Assign(new Value(new Literal('_')), ast, '=')]);
@ -33,7 +33,7 @@
return cb(null, vm.runInContext(js, context, filename));
} catch (_error) {
err = _error;
err.code || (err.code = input);
updateSyntaxError(err, input);
return cb(err);
}
}
@ -133,13 +133,13 @@
module.exports = {
start: function(opts) {
var build, major, minor, repl, _ref;
var build, major, minor, repl, _ref1;
if (opts == null) {
opts = {};
}
_ref = process.versions.node.split('.').map(function(n) {
_ref1 = process.versions.node.split('.').map(function(n) {
return parseInt(n);
}), major = _ref[0], minor = _ref[1], build = _ref[2];
}), major = _ref1[0], minor = _ref1[1], build = _ref1[2];
if (major === 0 && minor < 8) {
console.warn("Node 0.8.0+ required for CoffeeScript REPL");
process.exit(1);

View File

@ -27,9 +27,7 @@ withPrettyErrors = (fn) ->
try
fn.call @, code, options
catch err
err.code or= code
err.filename or= options.filename
throw err
throw helpers.updateSyntaxError err, code, options.filename
# Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
#
@ -161,9 +159,7 @@ compileFile = (filename, sourceMap) ->
# As the filename and code of a dynamically loaded file will be different
# from the original file compiled with CoffeeScript.run, add that
# information to error so it can be pretty-printed later.
err.filename or= filename
err.code or= stripped
throw err
throw helpers.updateSyntaxError err, stripped, filename
answer

View File

@ -146,10 +146,20 @@ exports.throwSyntaxError = (message, location) ->
# Instead of showing the compiler's stacktrace, show our custom error message
# (this is useful when the error bubbles up in Node.js applications that
# compile CoffeeScript for example).
Object.defineProperty? error, 'stack', get: -> @toString()
error.stack = error.toString()
throw error
# Update a compiler SyntaxError with source code information if it didn't have
# it already.
exports.updateSyntaxError = (error, code, filename) ->
# Avoid screwing up the `stack` property of other errors (i.e. possible bugs).
if error.toString is syntaxErrorToString
error.code or= code
error.filename or= filename
error.stack = error.toString()
error
syntaxErrorToString = ->
return Error::toString.call @ unless @code and @location

View File

@ -3,7 +3,7 @@ path = require 'path'
vm = require 'vm'
nodeREPL = require 'repl'
CoffeeScript = require './coffee-script'
{merge} = require './helpers'
{merge, updateSyntaxError} = require './helpers'
replDefaults =
prompt: 'coffee> ',
@ -30,7 +30,7 @@ replDefaults =
cb null, vm.runInContext(js, context, filename)
catch err
# AST's `compile` does not add source code information to syntax errors.
err.code or= input
updateSyntaxError err, input
cb err
addMultilineHandler = (repl) ->

View File

@ -8,7 +8,6 @@ assertErrorFormat = (code, expectedErrorFormat) ->
throws (-> CoffeeScript.run code), (err) ->
err.colorful = no
eq expectedErrorFormat, "#{err}"
eq expectedErrorFormat, err.stack
yes
test "lexer errors formating", ->