How to get your (JS) Stack Trace back
Published 2021-7-17Today I was trying to in inspect the call stack in JavaScript by doing a little
error stack trace hack (my old friend console.log(new Error('stack').stack)
),
but I instead was met with a new foe: CallSite{}
.
I did this:
console.log(err.stack);
And instead of a normal descriptive call stack, I got this:
[
CallSite{}, CallSite{},
CallSite{}
]
Now, on the flip side, I did actually get the stack trace when I
ran console.log(err)
, but it came out as an arr.join(',')
-looking string.
[/home/app/node_modules/foobar/foo.js:164:15,Array.reduce (<anonymous>),convertPlainObject (/home/app/node_modules/foobar/bar.js:159:27),/home/app/node_modules/foobar/bar.js:69:14,Array.map (<anonymous>),convertArgs (/home/app/node_modules/foobar/bar.js:57:15)]
Thankfully, console.log(err.toString())
still showed a useful message.
Unexpected error #Id10t: check for problems between the keyboard and the chair.
Error.prepareStackTrace
The reason that you're getting the array of CallSite
objects rather than the
pre-formatted stack string that you're used to is that Error.prepareStackTrace
has been modified.
I'd suggest using rg
(or grep
, if you hate
yourself) to look through your code for a place where Error.prepareStackTrace
is referenced and modified in some way:
rg 'Error\.prepareStackTrace' ./
If you can't find it in your code, check excluded files and folders, such as
your node_modules
too:
rg -uuu 'Error\.prepareStackTrace' ./
Did you go looking for line numbers?
I'd say that there's at least half a chance that what you're going to find is
some _getCallerFile
function that you or someone else copied from a
StackOverflow question similar to this one:
https://stackoverflow.com/questions/16697791/nodejs-get-filename-of-caller-function
Update: I used my superpowers to edit the original answer so that it is now correct.
How to fix?
Wherever Error.prepareStackTrace
has been modified, go back and set it to its
previous value.
For example:
diff --git a/getCallerFile.js b/getCallerFile.js
index 114ccfd..5013be0 100644
--- a/getCallerFile.js
+++ b/getCallerFile.js
@@ -1,9 +1,13 @@
function _getCallerFile() {
+ var _pst = Error.prepareStackTrace;
+
var err = new Error();
Error.prepareStackTrace = function (err, stack) {
return stack;
};
var stack = err.stack;
+ Error.prepareStackTrace = _pst;
return stack.slice(0, 3).pop().getFileName();
}
Or, for your copy-paste needs:
/**
* @license
* getCallerFile.js - get the calling function's filename
*
* Written in 2021 by AJ ONeal <coolaj86@gmail.com>
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along with
* this software. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
*/
function _getCallerFile() {
var _pst = Error.prepareStackTrace;
var err = new Error();
Error.prepareStackTrace = function (err, stack) {
return stack;
}
var stack = err.stack;
Error.prepareStackTrace = _pst;
return stack.slice(0, 3).pop().getFileName();
}
By AJ ONeal
Did I make your day?
Buy me a coffee
(you can learn about the bigger picture I'm working towards on my patreon page )