Today 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

If you loved this and want more like it, sign up!


Did I make your day?
Buy me a coffeeBuy me a coffee  

(you can learn about the bigger picture I'm working towards on my patreon page )