Подтвердить что ты не робот

Получить имя и строку функции вызова в node.js

Как можно получить имя и строку функции, которая вызвала текущую? Я хотел бы иметь такую элементарную функцию отладки (npmlog определяет log.debug):

function debug() {
  var callee, line;
  /* MAGIC */
  log.debug(callee + ":" + line, arguments)
}

При вызове из другой функции это будет примерно так:

function hello() {
   debug("world!")
}
// outputs something like:
// "hello:2 'world!'"

Для ясности то, что я хочу, по сути аналогично этому в Python:

import inspect
def caller():
    return inspect.stack()[2][3]
// line no from getframeinfo().lineno

Есть ли эквивалент узла для этого?

4b9b3361

Ответ 1

Используя информацию отсюда: Доступ к номеру строки в JavaScript V8 (Chrome и Node.js)

вы можете добавить некоторые прототипы для доступа к этой информации из V8:

Object.defineProperty(global, '__stack', {
get: function() {
        var orig = Error.prepareStackTrace;
        Error.prepareStackTrace = function(_, stack) {
            return stack;
        };
        var err = new Error;
        Error.captureStackTrace(err, arguments.callee);
        var stack = err.stack;
        Error.prepareStackTrace = orig;
        return stack;
    }
});

Object.defineProperty(global, '__line', {
get: function() {
        return __stack[1].getLineNumber();
    }
});

Object.defineProperty(global, '__function', {
get: function() {
        return __stack[1].getFunctionName();
    }
});

function foo() {
    console.log(__line);
    console.log(__function);
}

foo()

Возвращает "28" и "foo" соответственно.

Ответ 2

У меня также было подобное требование. Я использовал свойство стека класса Error, предоставляемое nodejs.
Я все еще изучаю node, поэтому возможны ошибки.

Ниже приводится объяснение тому же. Также созданный модуль npm для того же, если хотите, вы можете проверить: 1. npm модуль 'logat'
2. git repo

предположим, что мы "логгер" с помощью метода "log"

var logger = {
 log: log
}
function log(msg){
  let logLineDetails = ((new Error().stack).split("at ")[3]).trim();
  console.log('DEBUG', new Date().toUTCString(), logLineDetails, msg);
}

Пример:

//suppose file name: /home/vikash/example/age.js
function getAge(age) {
    logger.log('Inside getAge function');    //suppose line no: 9
}

Результат выше Пример:

    DEBUG on Sat, 24 Sept 2016 12:12:10 GMT at getAge(/home/vikash/example/age.js:9:12)
    Inside getAge function

Ответ 3

Я нашел и установил node-stack-trace модуль (установлен с npm install stack-trace), а затем определил echo как:

function echo() {
  var args, file, frame, line, method;
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];

  frame = stackTrace.get()[1];
  file = path.basename(frame.getFileName());
  line = frame.getLineNumber();
  method = frame.getFunctionName();

  args.unshift("" + file + ":" + line + " in " + method + "()");
  return log.info.apply(log, args); // changed 'debug' to canonical npmlog 'info'
};

Ответ 4

Следующий код использует только основные элементы. Он анализирует стек из экземпляра ошибки.

"use strict";
function debugLine(message) {
    let e = new Error();
    let frame = e.stack.split("\n")[2];
    let lineNumber = frame.split(":")[1];
    let functionName = frame.split(" ")[5];
    return functionName + ":" + lineNumber + " " + message;
}
function myCallingFunction() {
    console.log(debugLine("error_message"));
}
myCallingFunction();

Это выводит что-то вроде myCallingFunction:10 error_message

Я извлек элементы ошибки в виде переменных (lineNumber, functionName), чтобы вы могли отформатировать возвращаемое значение любым удобным для вас способом.

Как примечание стороны: use strict; Заявление не является обязательным и может использоваться, только если весь ваш код использует строгий стандарт. Если ваш код не совместим с этим (хотя так и должно быть), вы можете удалить его.