How can one get the file path of the caller function in node.js?

Here is some sample code from three files:

// foo.js
var myFunc = require("./myFunc");
function foo(){
   myFunc("message");
}

// bar.js
var myFunc = require("./myFunc");
function bar(){
   myFunc("message");
}

// myFunc.js
module.exports = myFunc;
function myFunc(arg1){
   console.log(arg1);
   // Here I need the file path of the caller function
   // For example, "/path/to/foo.js" and "/path/to/bar.js"
}

I need to get the file path of the caller function dynamically, without any extra argument passing, for myFunc.

You need to fiddle with the inner workings of v8. See: the wiki entry about the JavaScript Stack Trace API.

I've based a little test on some code in a proposed commit and it seems to work. You end up with an absolute path.

// omfg.js

module.exports = omfg

function omfg() {
  var caller = getCaller()
  console.log(caller.filename)
}

// private

function getCaller() {
  var stack = getStack()

  // Remove superfluous function calls on stack
  stack.shift() // getCaller --> getStack
  stack.shift() // omfg --> getCaller

  // Return caller's caller
  return stack[1].receiver
}

function getStack() {
  // Save original Error.prepareStackTrace
  var origPrepareStackTrace = Error.prepareStackTrace

  // Override with function that just returns `stack`
  Error.prepareStackTrace = function (_, stack) {
    return stack
  }

  // Create a new `Error`, which automatically gets `stack`
  var err = new Error()

  // Evaluate `err.stack`, which calls our new `Error.prepareStackTrace`
  var stack = err.stack

  // Restore original `Error.prepareStackTrace`
  Error.prepareStackTrace = origPrepareStackTrace

  // Remove superfluous function call on stack
  stack.shift() // getStack --> Error

  return stack
}

And a test that includes omfg module:

#!/usr/bin/env node
// test.js

var omfg = require("./omfg")

omfg()

And you will get on the console the absolute path of test.js.


EXPLANATION

This is not so much a "node.js" issue as it is a "v8" issue.

See: Stack Trace Collection for Custom Exceptions

Error.captureStackTrace(error, constructorOpt) adds to the error parameter a stack property, which evaluates by default to a String (by way of FormatStackTrace). If Error.prepareStackTrace(error, structuredStackTrace) is a Function, then it is called instead of FormatStackTrace.

So, we can override Error.prepareStackTrace with our own function that will return whatever we want--in this case, just the structuredStackTrace parameter.

Then, structuredStackTrace[1].receiver is an object representing the caller.

sindresorhus/caller-path: Get the path of the caller module, Contribute to sindresorhus/caller-path development by creating an account on GitHub. GitHub is home to over 40 million developers working together to host and review code, Branch: master. New pull request. Find file. Clone or download '/Users/sindresorhus/dev/unicorn/foobar.js' console.log(callerPath({​depth: 1}));  thanks for the explanation, now I can get the file name of the caller function. – Dexter Nov 12 '12 at 7:35 This helped me figure out where the memory leak was occurring!!!

Or instead of fiddling with inner workings of the V8 engine, you use module.parent.filename to get absolute path to the module that required your module. As demonstrated here: https://gist.github.com/capaj/a9ba9d313b79f1dcd9a2

Just keep in mind that modules are cached, so if any other file requires it and calls it, it will always be the path to the first importer.

caller-path, Get the path of the caller function. Get unlimited public & private packages + package-based permissions npm i caller-path Total Files. 5  To do this, we need to create a recursive function that can call itself when dealing with sub-directories. And we also need the function to go through each of the sub-directories and add any new files it encounters. When the function is finished, it should return an array with all the files it encountered.

Nodejs: get filename of caller function, I need to get the file path of the caller function dynamically, without any extra argument passing, for myFunc . Answers: You need to fiddle with  Node JS Get All Files In Directory Example /* Call file_operator module function to get child folders and files of parent folder. How To Get Real File Path

You can make use of caller-callsite package:

console.log(callerCallsite().getFileName());

The alternatives are callsites and stackman packages. callsites provides you with all call sites ("stack frame" in v8 terminology). And stackman gives the call sites decorated with custom functions and behavior. Source context, among other things. Which is lines of code surrounding call site line. Also it makes use of source maps if available.

The issue with stackman is that it returns call sites asynchronously. Which is not particularly usable when running from debugger.

Here's some code I used which you might find useful:

var callsites = require('callsites');
var util = require('util');
var path = require('path');
function printStackTrace() {
    callsites().slice(1).forEach(function(cs) {
        printCallSite(cs);
    });
}
function printCallSite(cs) {
    console.log(util.format('%s:%i',
        path.relative(process.cwd(), cs.getFileName()),
        cs.getLineNumber()));
    console.log('  getTypeName(): ' + cs.getTypeName());
    console.log('  getFunctionName(): ' + cs.getFunctionName());
    console.log('  getMethodName(): ' + cs.getMethodName());
    // console.log('  getEvalOrigin(): ' + cs.getEvalOrigin());
    // console.log('  isTopLevel(): ' + (cs.isTopLevel ? cs.isTopLevel() : null));
    // console.log('  isEval(): ' + cs.isEval());
    // console.log('  isNative(): ' + cs.isNative());
    // console.log('  isConstructor(): ' + cs.isConstructor());
}
function getCallSiteIndexes(cond) {
    var cond = cond || function() { return true; };
    var options = arguments[1] || {};
    var css = options['callsites'] || callsites().slice(1);
    var r = [];
    for (var i = 0; i < css.length; i++) {
        var cs = css[i];
        if (cond(cs)) {
            if (options['first'])
                return i;
            r.push(i);
        }
    }
    return options['first'] ? null : r;
}
function getFirstCallSiteIndex(cond) {
    var css = callsites().slice(1);
    return getCallSiteIndexes(cond, {first: true, callsites: css});
}
function getCallSites(cond) {
    var options = arguments[1] || {};
    var css = options['callsites'] || callsites().slice(1);
    var indexes = getCallSiteIndexes(cond,
        Object.assign({}, {callsites: css}, options));
    if (options['first'])
        return css[indexes];
    return indexes.map(function(i) {
        return css[i];
    });
}
function getFirstCallSite(cond) {
    var css = callsites().slice(1);
    return getCallSites(cond, {first: true, callsites: css});
}

fucntion f() {
    var firstCS = callsites()[0];
    var runAsChildCSIndex = getFirstCallSiteIndex(function(cs) {
        return cs.getFileName() == firstCS.getFileName() && cs.getFunctionName() == 'Compiler.runAsChild';
    });
    if (runAsChildCSIndex) {
        printCallSite(callsites()[runAsChildCSIndex + 1]);
    } else {
        var compilerRunCS = getFirstCallSite(function(cs) {
            return cs.getFileName() == firstCS.getFileName() && cs.getFunctionName() == 'Compiler.run';
        });
        printCallSite(compilerRunCS);
    }
    ...

Function.caller, I wonder how-to get an absolute path of a caller of a function? Let say that: in file a.js I call b() ; b() is a function defined in file b.js . a.js requires  How can one get the name and line of a function that called the current one? I would like to have a rudimentary debugging function like this (with npmlog defining log.debug): function debug() { var callee, line; /* MAGIC */ log.debug(callee + ":" + line, arguments) } When called from another function it would be something like this:

Node.js Recipes, How can one get the file path of the caller function in node.js? #NodeJS. Node implements File I/O using simple wrappers around standard POSIX functions. The Node File System (fs) module can be imported using the following syntax − Every method in the fs module has synchronous as well as asynchronous forms. Asynchronous methods take the last parameter as the completion function callback and the first parameter of

Modules, Functions and objects are added to the root of a module by specifying additional properties on the special For a file foo.js , this will be true if run via node foo.js , but false if run by require('./foo') . Let's say that we wanted to have the folder at​  There is a lot more that could be done here - saving logs to a file, pushing them to a database, setting custom colors and formatting the output - but by the time you want that much functionality from your custom logging function, it might be time to use an already-existing library.

How to find out the caller function in JavaScript?, How to get client IP address using JavaScript ? Introduction to React-Redux · JavaScript Interview Questions and Answers | Set 3 · File uploading in React.js · How  encoding is an optional parameter that specifies the type of encoding to read the file. Possible encodings are 'ascii', 'utf8', and 'base64'. If no encoding is provided, the default is null. callback is a function to call when the file has been read and the contents are ready - it is passed two arguments,

Comments
  • stackoverflow.com/questions/16697791/…
  • Possible duplicate of Nodejs: get filename of caller function
  • Hi, I am new bie in nodejs, Can you please tell me what is actually happening in getStack() ?
  • thanks for the explanation, now I can get the file name of the caller function.
  • This helped me figure out where the memory leak was occurring!!! Thanks a lot for this!!!
  • Yes but if you have multiple module.exports between the function and the caller, it doesn't work.
  • @Sylvain in that case, you should be able to traverse parents all the way. That might be problematic, if you are loading modules dynamically, but in most cases, you wouldn't do that.
  • @Capaj I was just going to call out Sylvain for the same thing, but that was because of the solution I was looking for, not the OP. The OP asked for the filename of the calling function, not calling module. Your answer fits my question perfectly, but doesn't match fully with the OP's question, so I'd have to agree with him. However, you saved me a lot of continued searching :D
  • Is there a way to get the caller's name every time your module is required instead of just the first caller (via parent)?
  • Ended up using github.com/sindresorhus/callsites, which at least works in Node, which is what I need.