-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #4558: Stack trace line numbers for scripts that compile CoffeeScript #4645
Conversation
…lename, or multiple anonymous scripts
…ps, more careful lookup of source maps especially for CoffeeScript code compiled within a Coffee script (. . . within a Coffee script, etc.)
…plaguing that command (something to do with module caching perhaps)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the change of this PR is basically:
- Handle
<anonymous>
differently. - Allow to fallback to recompiling in more cases.
I guess that's pretty harmless? Not sure if the approach is fully correct, but if it works better than before I guess it's fine.
I'm not sure I understand completely the issue, the obstacles and the solution, but I don't think there's any harm merging this.
Yeesh this looks a little hacky. Can we not correctly associate the scripts with the maps by maintaining a correct lookup somehow? |
That’s kind of what’s happening now. The issue is that there are multiple maps per file when a file runs console.log 'Hello!'
CoffeeScript.run '''
CoffeeScript = require './lib/coffeescript
CoffeeScript.compile ''
throw new Error 'Some Error'
''' This generates three source maps, all under There is a method called So instead of that, I search through the array of source maps to find the first one that has a matching source map for the exception. This is potentially even less foolproof, as source maps could easily have overlapping matches (especially If you can think of a better solution, please suggest it. I agree that a hacky, non-foolproof matching of source maps line/column pairs is far from ideal, but it’s better than returning |
So what do we think? @jashkenas or @lydell, is this okay to merge in? If you think of a better solution for the line numbers problem than this one, we can always submit a new PR later. |
I don't doubt that you've found the best solution that can be thought of for the moment, but it would be nice to clear any confusion up before merging :) |
I hope not! We do have tests for that, though.
They weren’t always correct before. If the exception was thrown in the topmost script (i.e. not a string passed to
So there’s a pretty long, tortured history.
|
IMO, we're good to go then. |
If we want to replicate the 1.12.1 behavior but keep the caching, we could cache the first appearance of each filename but ignore any subsequent appearances. That would be equivalent to the file-open approach, but it would share the bug with that version of incorrect line numbers of child scripts. This bug is more important than it might seem, because lots of our own tests are compilations of child scripts. |
Just throwing out thoughts here -- but what if we stopped using the filename as the key to the source map lookup, and instead used something more robust: like the SHA of the source code to-be-compiled? |
I thought of that. Unfortunately the issue is that when the runtime throws the exception, all it supplies is the filename, not the source. We have only a filename to go on to find the source/source map. |
Ah, I see. In that case your fix looks perfect. That said, it seems like with any engine providing source map support, there really ought to be a way to link the specific JS to the map directly. |
Yes. It seems pretty clear that the designers of the JavaScript stack trace never imagined that there might be multiple different sources with the same filename (or that someone might be rewriting their stack trace, for that matter). |
Fixes #4558. Also fixes the
cake release
command, which broke somewhere around when Node 8 came out.Feedback welcome. So basically the issue in #4558 is that when you have a CoffeeScript file that itself has
CoffeeScript = require 'coffeescript'
and then something likeCoffeeScript.compile
, there’s basically a script within a script here and we need to preserve the source maps within the source maps, so that stack trace line numbers work correctly. Unfortunately the child scripts are all cached as<anonymous>
, and the runtime always throws errors referencing the filename of the top-level script, so there’s some dark arts involved in picking which source map to use for patching the error stack trace. The method I’ve chosen isn’t foolproof, if you have multiple source maps that happen to have identical code or mappings, but it should work most of the time. I don’t see how to get a foolproof method without the runtime providing the full source of the “file” throwing the error, which it doesn’t (as far as I can tell). There’s more gory detail in the comments of the PR.