Let's say I have a language that looks like
print "Hello World"
which transpiles to
var $__Helpers = {
print: function(s) {
if (typeof s != 'string')
throw new TypeError('String expected');
console.log(s);
}
};
$__Helpers.print("Hello World");
If a user of this language does
print 5
a TypeError will be thrown by $__Helpers.print
saying "String expected". I want the developer tools to show the print 5
line as the originating call for this error. I know how to get my source map to show a call stack that looks like
transpiled_script.js:2
original_script.os:1
where transpiled_script.js:2
is the script and line number for the call to the $__Helpers.print
function and original_script.os:1
is the script and line number for the call to print 5
. I want to have the dev tools just ignore the top call to transpiled_script.js
(which is only an implementation detail of my transpiler) and only show the call from the original script (which is the part that they should debug in their own script).
I clearly can't simply map transpiled_script.js:2
to original_script.os:1
because there could be multiple calls to print
inside original_script.os
, so it's not a 1 to 1 relationship.
Is there any way to do this?
(I am using escodegen to generate my source and my source map (escodegen uses the Node mozilla/source-map module), so having a way to tell escodegen or mozilla/source-map to do this would be ideal, but I can override escodegen's output if that's not possible.)
You may split the trace and print the required lines of it
var $__Helpers = {
print: function(s) {
if (typeof s != 'string'){
var err = new TypeError('String expected');
var trace = err.stack.split('\n')
console.error(trace[0]); // TypeError: string expected
console.error(trace[2]); // the line who called the function, probably
//original_script.os:1, or whatever line number the call was from
//quit the script
}
console.log(s);
} };
EDIT: a better solution, is to replace the trace of the error, than throw it, the code now look like this:
var $__Helpers = {
print: function(s) {
if (typeof s != 'string'){
var err = new TypeError('String expected: Got'+s);
err.stack = err.stack.replace(/\n.*transpiled_script\.js.*?\n/g,"\n");
throw err;
}
console.log(s);
} };
this will work for errors in nested called too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With