jashkenas / jashkenas/coffeescript
Bug: Stack traces from CoffeeScript.eval have JS line numbers
- Dominant language
- CoffeeScript
- Stars
- 16.6k
- Forks
- 2k
- PR merge metrics
- No merged PRs in 30d
Description
In what I believe is a bug, line numbers in stack traces from errors thrown by CoffeeScript code executed via `CoffeeScript.eval()` (in NodeJS) give the JavaScript line numbers instead of the CoffeeScript line numbers.
### Simple example
```coffee
CoffeeScript = require 'coffeescript'
CoffeeScript.eval '''
if undefined.foo
weird = true # cause var hoist to shift lines
'''
```
The resulting stack trace and initial message uses a line number of 3 (**current behavior**) instead of 1 (**expected behavior**):
```
evalmachine.:3
if ((void 0).foo) {
^
TypeError: Cannot read property 'foo' of undefined
at evalmachine.:3:14
at Script.runInThisContext (vm.js:91:20)
at Object.runInThisContext (vm.js:298:38)
at Object.CoffeeScript.eval (...\node_modules\coffeescript\lib\coffeescript\index.js:127:17)
at repl:2:28
at repl:3:3
...
```
### More real example with filename
In my application, the eval'd string actually comes from a `.coffee` file, and I can get the **filename** to appear correctly with enough options to `CoffeeScript.eval` (though admittedly I don't understand why so many arguments are needed for this to happen), yet the **line numbers** remain the same.
```coffee
CoffeeScript.eval 'if undefined.foo then weird = true',
filename: 'test.coffee'
sourceFiles: ['test.coffee']
inlineMap: true
```
results in:
```
test.coffee:3
if ((void 0).foo) {
^
TypeError: Cannot read property 'foo' of undefined
at evalmachine.:3:14
```
### Workaround
In my application, I constructed [a workaround](https://github.com/edemaine/svgtiler/blob/c44edcf5fdf5a7f30711732e6a30fb9df08c4c4f/src/svgtiler.coffee#L327-L347) that corrects the line number in the initial message by using `CoffeeScript.compile` to get a source map, looking up/mapping the line number, and modifying the error's stack trace.
### Proposed Solution
I think it would make sense for `CoffeeScript.eval` to do this kind of mangling of error stack traces. The [REPL](https://github.com/jashkenas/coffeescript/blob/master/src/repl.coffee#L66-L69) already does mangling of `SyntaxError`s via [`helpers.updateSyntaxError`](https://github.com/jashkenas/coffeescript/blob/master/src/helpers.coffee#L200-L237), and some of this code can probably be shared. (It was the inspiration for my workaround.)
### Related issues
Possibly related to #5129 and #4645. In particular, errors from the REPL seem to start every error with `repl:2` whereas `repl:1` would make more sense. I believe this is the same issue, so would also get fixed (though REPL seems less important to me).
### Environment
* CoffeeScript version: 2.3.1
* Node.js version: 10.8.0
* Operating system: Windows 10
Contributor guide
Research direction
Start at CoffeeScript.eval and inspect the referenced src/repl.coffee and src/helpers.coffee, especially the existing syntax-error handling and source-map behavior. Use the two examples as regression cases; done means eval-generated stack messages and locations report CoffeeScript line numbers while preserving filenames, with related REPL behavior considered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- coffeescript, node.js
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 42/100