kramer65
kramer65

Reputation: 53873

How to get filename and line number of where a function is called in Node?

When working in Python I always have this simple utility function which returns the file name and line number from where the function is called:

from inspect import getframeinfo, stack
def d():
    """ d stands for Debug. It returns the file name and line number from where this function is called."""
    caller = getframeinfo(stack()[1][0])
    return "%s:%d -" % (caller.filename, caller.lineno)

So in my code I simply put a couple debug lines like this to see how far we get before some error occurs:

print d()
# Some buggy code here
print d()
# More buggy code here
print d(), 'here is the result of some var: ', someVar

This works really well for me because it really helps debugging quickly.

I'm now looking for the equivalent in a node backend script. I was searching around but I can't find anything useful (maybe I'm looking for the wrong words?).

Does anybody know how I can create a Javascript/nodejs function which outputs the file name and line number from where the function is called? All tips are welcome!

Upvotes: 20

Views: 16621

Answers (4)

lilezek
lilezek

Reputation: 7344

You can create an Error to get where the Error is, and its stack trace. Then you can put that into a function, to get the line where it is.

function thisLine() {
  const e = new Error();
  const regex = /\((.*):(\d+):(\d+)\)$/
  const match = regex.exec(e.stack.split("\n")[2]);
  return {
    filepath: match[1],
    line: match[2],
    column: match[3]
  };
}

console.log(thisLine());

This works for me in Google Chrome.

And also in node.

Note to @j08691's comment:

Both this and this seem to be using lineNumber, which is not present (as far as I could test) in NodeJS.

Upvotes: 32

M. Hamza Rajput
M. Hamza Rajput

Reputation: 10246

Printing line number with custom string

const moment = require('moment');
const log = console.log;
const path = require('path');

function getTime(time) { return moment().format('YYYY-MM-DD HH:mm:ss') };

function line(num = 2) {
    const e = new Error();
    const regex = /\((.*):(\d+):(\d+)\)$/
    const match = regex.exec(e.stack.split("\n")[num]);
    const filepath = match[1];
    const fileName = path.basename(filepath);
    const line = match[2];
    const column = match[3];
    return {
        filepath,
        fileName,
        line,
        column,
        str: `${getTime()} - ${fileName}:${line}:${column}`
    };
}

log(line().str, "mylog1");
log(line().str, "mylog2");
log(line().str, "mylog3");

OUTPUT

2021-11-22 13:07:15 - test.js:44:5 mylog1
2021-11-22 13:07:15 - test.js:45:5 mylog2
2021-11-22 13:07:15 - test.js:46:5 mylog3

Upvotes: 2

Alnitak
Alnitak

Reputation: 339816

The only way I've found to get anything relating to line numbers is to trap the window.onerror function, and when there's an error that will get passed the error message, the file URL and the line number:

window.onerror = function(msg, url, line) {
    alert(msg + "\n" + url + ":" + line);
};

This works for me on Chrome - I don't know about other browsers.

EDIT when this answer was given in Feb' 15 there was no mention of NodeJS in the question. That was only added in November '17.

Upvotes: 0

yawningphantom
yawningphantom

Reputation: 446

You can use this gulp plugin gulp-log-line . It Logs file and line number without the extra cost of reading the stack.

you just have to install gulp and gulp-log-line using the npm install gulp --save and npm install gulp-log-line command. after that you need to create and write the below code in gulpfile.js and run gulp log-line to create a duplicate file in the build folder :-

var gulp = require('gulp');
var logLine = require('gulp-log-line');
gulp.task('line-log', function() {
  return gulp.src("file.js", {buffer : true})
//Write here the loggers you use.
    .pipe(logLine(['console.log', 'winston.info']))
    .pipe(gulp.dest('./build'))

})

gulp.task('default', ['line-log'])

Example

file.js :-

console.log('First log')
var someVariable
console.log('Second log')

Becomes

console.log('file.js:1', 'First log')
var someVariable
console.log('file.js:3', 'Second log')

Upvotes: 0

Related Questions