Node.js中如何捕捉当前堆栈?
一、捕捉堆栈的时机
Node.js中捕捉堆栈只有在new Error()
时会进行自动捕捉。初始化Error实例时调用Error.captureStackTrace(this)
,为实例捕捉堆栈并格式化成字符串塞进实例的stack
属性中。
参考:http://nodejs.cn/api/errors.html#errors_error_capturestacktrace_targetobject_constructoropt
二、如何不用new Error()
捕捉当前调用堆栈?
const obj = Object.create(null); // 初始化一个空对象
Error.captureStackTrace(obj); // 捕捉堆栈并塞入obj.stack属性中
obj.stack; // 直接访问即可获取堆栈
三、自定义堆栈格式
默认情况下v8内置了堆栈的格式化函数Error.prepareStackTrace()
,和堆栈的层级捕捉限制Error.stackTraceLimit
。我们如果想定制stack
的内容,只要替换这两个v8内置的方法即可:
/**
* Capture call site stack from v8.
* https://v8.dev/docs/stack-trace-api
*/
function myPrepareStackTrace(obj, stack) {
// do something stack format.
// ...
return stack;
}
// 替换内置stackTraceLimit、prepareStackTrace
const limit = Error.stackTraceLimit;
const prep = Error.prepareStackTrace;
Error.prepareStackTrace = myPrepareStackTrace; // 替换成我们自定义方法
Error.stackTraceLimit = 4; // 只捕捉前4层堆栈
// 捕捉放入空对象
const obj = Object.create(null);
Error.captureStackTrace(obj);
obj.stack; // 获得自定义堆栈
// 还原内置stackTraceLimit、prepareStackTrace
Error.prepareStackTrace = prep;
Error.stackTraceLimit = limit;
另外,myPrepareStackTrace
中的stack
参数是原始堆栈信息,其结构是一个包含stackTraceLimit
个CallSite
对象的数组,CallSite
拥有丰富的api可以获取每一个堆栈站点的详细信息如:getFileName()
、getLineNumber()
、getColumnNumber()
等。
参考:https://v8.dev/docs/stack-trace-api