jashkenas / jashkenas/coffeescript

Bug: Stack traces from CoffeeScript.eval have JS line numbers

Open
#5,216 8 comments 1 reaction 0 assignees View on GitHub
bug help wanted
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.