关于Error.captureStackTrace
2016-09-26 10:44
260 查看
原文:关于Error.captureStackTrace
在一些Node.js程序中,有时会看到
既然JavaScript语言标准中没有定义captureStackTrace,那就只能从Node.js的文档中去寻找答案了。Node.js中,关于Error.captureStackTrace的描述是这样的:
Error.captureStackTrace(targetObject[, constructorOpt])
在
以下是一个最简单的例子:
与
除了targetObject, captureStackTrace还接受一个类型为function的可选参数
进一步的探究发现,
在浏览器领域,除了使用V8引擎的Google Chrome,其它浏览器中不存在
为了不向使用者暴露自定义Error类的内部细节,在自定义Error类内部使用captureStackTrace时,往往会传入constructorOpt参数,其值即为自定义 Error类的构造函数。具体做法有3种:
除了自定义Error类的使用场景,在JavaScript程序中,当需要获知调用堆栈信息时,都可以通过调用
与这种做法相比,可以很明显的看到,使用
在一些Node.js程序中,有时会看到
Error.captureStackTrace()这一语句,用于处理堆栈信息。该语句的标准定义是什么?如何使用?本文将就这些问题做一些探讨。
标准定义
从字面上来看,captureStackTrace应该是Error构造函数自身的一个方法。因此,很自然的想到从ECMAScript标准文档中寻找答案。不幸的是,在标准文档的19.5 Error Objects章节中,并未提及任何有关captureStackTrace的内容。看来,这一语句和语言的运行环境有关,并非由JavaScript标准所定义。既然JavaScript语言标准中没有定义captureStackTrace,那就只能从Node.js的文档中去寻找答案了。Node.js中,关于Error.captureStackTrace的描述是这样的:
Error.captureStackTrace(targetObject[, constructorOpt])
在
targetObject中添加一个
.stack属性。对该属性进行访问时,将以字符串的形式返回
Error.captureStackTrace()语句被调用时的代码位置信息(即:调用栈历史)。
以下是一个最简单的例子:
const myObject = {}; Error.captureStackTrace(myObject); myObject.stack // 效果与`new Error().stack`类似
与
errorObject.stack不同的是,
errorObject.stack所返回的字符串的第一行一般遵循
ErrorType: message的形式,而使用captureStackTrace所得到的字符串的第一行则一般以
targetObject .toString()开头。
除了targetObject, captureStackTrace还接受一个类型为function的可选参数
constructorOpt,当传递该参数时,调用栈中所有constructorOpt函数之上的信息(包括constructorOpt函数自身),都会在访问
targetObject.stack时被忽略。当需要对终端用户隐藏内部的技术细节时,constructorOpt参数会很有用。比如:
function MyError() { Error.captureStackTrace(this, MyError); } // 如果没有向captureStackTrace传递MyError参数,则在访问.stack属性时,MyError及其内部信息将会出现在堆栈信息中。当传递MyError参数时,这些信息会被忽略。 new MyError().stack
进一步的探究发现,
Error.captureStackTrace()并非Node.js所创造,而是源自V8引擎的Stack Trace API(事实上,Node.js的Error类中,所有与stack trace有关的内容均依赖于V8的Stack Trace API)。从语法上来说,Node.js中的
Error.captureStackTrace()与V8引擎中所暴露的接口完全一致。
在浏览器领域,除了使用V8引擎的Google Chrome,其它浏览器中不存在
Error.captureStackTrace()这一接口。
使用场景
由于Error.captureStackTrace()可以返回调用堆栈信息,因此在自定义Error类的内部经常会使用该函数,用以在error对象上添加合理的stack属性。上文中的MyError类即是一个最简单的例子。
为了不向使用者暴露自定义Error类的内部细节,在自定义Error类内部使用captureStackTrace时,往往会传入constructorOpt参数,其值即为自定义 Error类的构造函数。具体做法有3种:
Error.captureStackTrace(this, MyError);将构造函数的变量名作为constructorOpt参数传入。这一做法比较简单、直接,但不利之处也比较明显:代码所要传达的是“忽略当前构造函数及其内部的堆栈调用信息”,而以具体的构造函数作为参数传入使得这一语句缺乏通用性,不利于程序的进一步抽象。
Error.captureStackTrace(this, this.constructor);通过
this.constructor传入constructorOpt参数。与上一种方法相比,这一方式更具通用性。在自定义Error类中使用captureStackTrace时,推荐采用该方法。
Error.captureStackTrace(this, arguments.callee);通过
arguments.callee将“当前函数”作为constructorOpt参数传入。不过,由于ES5的strict模式中禁用了
arguments.callee,因此不建议使用该写法。
除了自定义Error类的使用场景,在JavaScript程序中,当需要获知调用堆栈信息时,都可以通过调用
Error.captureStackTrace()来实现。以往如果需要获知调用堆栈信息,一般的做法是抛出一个Error对象并立即加以捕捉,通过访问该对象的stack属性来获得调用堆栈。一个简单的例子如下:
try { throw new Error(); } catch (e) { // e.stack 中包含了堆栈数据,可以进行处理从而忽略不感兴趣的堆栈信息 }
与这种做法相比,可以很明显的看到,使用
Error.captureStackTrace()会更简洁、易用,也更优雅;而这,也许就是V8中添加
Error.captureStackTrace()的原因。
相关文章推荐
- 把e.printStackTrace的堆栈信息打印在log.error()中
- 关于Java正则引起的StackOverFlowError问题以及解决方案
- 关于CLOSE BY CLIENT STACK TRACE
- 关于错误 Error opening trace file: Permission denied (13)
- Error Error occurred running Grails CLI: No profile found for name [web]. (Use --stacktrace to see
- 关于e.printStackTrace()
- The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact
- 关于:java.lang.VerifyError: Expecting a stackmap frame at branch target
- 关于MyEclipse8.5 错误 background indexer crash recovery java.lang.stackoverflowerror
- 把e.printStackTrace的堆栈信息打印在log.error()中
- 关于CLOSE BY CLIENT STACK TRACE
- 关于CLOSE BY CLIENT STACK TRACE
- 关于CLOSE BY CLIENT STACK TRACE 之二
- 把e.printStackTrace的堆栈信息打印在log.error()中
- How to get the full error stack trace of SharePoint
- DB_RUNRECOVERY: Fatal error, run database recovery StackTrace问题的解决办法
- 关于CLOSE BY CLIENT STACK TRACE 之一
- stack-trace error in Emacs for ecb
- 关于MyEclipse8.5 错误 background indexer crash recovery java.lang.stackoverflowerror
- The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.