You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// hubba.test.js
function BadCode() {
throw new Error('noo');
}
function run(fn) {
fn();
}
run(BadCode);
compiled to:
"use strict";
function BadCode() {
throw new Error('noo');
}
function run(fn) {
fn();
}
run(BadCode);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJCYWRDb2RlIiwiRXJyb3IiLCJydW4iLCJmbiJdLCJzb3VyY2VzIjpbImh1YmJhLnRlc3QuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gQmFkQ29kZSgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdub28nKTtcbn1cblxuZnVuY3Rpb24gcnVuKGZuKSB7XG4gIGZuKCk7XG59XG5cbnJ1bihCYWRDb2RlKTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxTQUFTQSxPQUFULEdBQW1CO0VBQ2pCLE1BQU0sSUFBSUMsS0FBSixDQUFVLEtBQVYsQ0FBTjtBQUNEOztBQUVELFNBQVNDLEdBQVQsQ0FBYUMsRUFBYixFQUFpQjtFQUNmQSxFQUFFO0FBQ0g7O0FBRURELEdBQUcsQ0FBQ0YsT0FBRCxDQUFIIn0=
Stack trace with source-mapping is wrong:
Error: noo
at fn (/Users/simen/repos/jest/hubba.test.js:2:9) <----- this stack frame should say `BadCode`
at run (/Users/simen/repos/jest/hubba.test.js:6:3)
at Object.<anonymous> (/Users/simen/repos/jest/hubba.test.js:9:1)
source-map-support's algorithm for getting the name of a stack frame: it checks the location of the next stack frame. That is why the bug is showing us at fn when it should be showing us at BadCode. The stack frame happens within BadCode, but the location of the next stack frame is the invocation site: fn()
We would see the same issue with the second stack frame if we did const runIt = run; runIt(BadCode) Because it's checking the name at the callsite, it's not checking the invokee's name.
Pretty sure this is not correct and stack frames actually expose additional information we can use to get the correct answer.
In addition to frame.getLineNumber() and frame.getColumnNumber(), we have frame.getEnclosingLineNumber() and frame.getEnclosingColumnNumber() which are the location of the invoked function. For example:
// getEnclosing*Number() gives us location A
// get*Number() gives us location B
/*A*/function run() {}
/*B*/run()
The text was updated successfully, but these errors were encountered:
I tried teaching source-map-support to map names at getEnclosingLineNumber and getEnclosingColumnNumber the way node does. This highlighted another problem with node's sourcemap implementation -- another place where we should be deviating from node. Thankfully, we're already there, because stable @cspotcode/source-map-support never attempts to map enclosing position.
In this example:
it('should fail', done => {
throw new Error();
});
The first stack frame's getEnclosing*Number() gives us the location of the done identifier, because that is where the function declaration starts. If we attempt to source-map the name at that position, we erroneously believe that the function's name is done. It is not; that is the name of the first argument to the function.
This example is great, because it shows how bad it can be to attempt these imperfect sourcemap checks. In the examples we looked at several days ago, we were mapping to the name of a function at its callsite, not its declared name. Both names referred to the same function. So it was imperfect, but semantically it sorta made sense.
But today's example is much worst: we are mapping to the name of an entirely different function. This isn't merely imperfect, it's flat-out wrong and misleading. done refers to a different function with a different purpose.
The fix is: never attempt to map names at the "enclosing" position. The sourcemap spec, as it is today, can't do that.
Uh oh!
There was an error while loading. Please reload this page.
From jestjs/jest#12786 (comment)
compiled to:
Stack trace with source-mapping is wrong:
source-map-support's algorithm for getting the name of a stack frame: it checks the location of the next stack frame. That is why the bug is showing us
at fn
when it should be showing usat BadCode
. The stack frame happens withinBadCode
, but the location of the next stack frame is the invocation site:fn()
We would see the same issue with the second stack frame if we did
const runIt = run; runIt(BadCode)
Because it's checking the name at the callsite, it's not checking the invokee's name.Pretty sure this is not correct and stack frames actually expose additional information we can use to get the correct answer.
In addition to
frame.getLineNumber()
andframe.getColumnNumber()
, we haveframe.getEnclosingLineNumber()
andframe.getEnclosingColumnNumber()
which are the location of the invoked function. For example:The text was updated successfully, but these errors were encountered: