合并重新出现的错误中的堆栈跟踪

我在这里重新抛出Sequelize承诺(蓝鸟)的错误。 首先,这是为了改变错误信息,但是当它出现时,这也产生了更多信息的堆栈跟踪。

这是类似的

sequelize.sync().catch(originalError => { const rethrownError = new Error(originalError.msg + ': ' + originalError.sql); throw rethrownError; }); 

其中originalError.stack不包含导致错误的行,但是它包含重要的信息,它来源于Sequelize和MySQL驱动程序:

 SequelizeDatabaseError: ER_KEY_COLUMN_DOES_NOT_EXITS: Key column 'NonExisting' doesn't exist in table at Query.formatError (...\node_modules\sequelize\lib\dialects\mysql\query.js:175:14) at Query._callback (...\node_modules\sequelize\lib\dialects\mysql\query.js:49:21) at Query.Sequence.end (...\node_modules\mysql\lib\protocol\sequences\Sequence.js:85:24) at Query.ErrorPacket (...\node_modules\mysql\lib\protocol\sequences\Query.js:94:8) at Protocol._parsePacket (...\node_modules\mysql\lib\protocol\Protocol.js:280:23) at Parser.write (...\node_modules\mysql\lib\protocol\Parser.js:74:12) at Protocol.write (...\node_modules\mysql\lib\protocol\Protocol.js:39:16) at Socket.<anonymous> (...\node_modules\mysql\lib\Connection.js:109:28) at emitOne (events.js:96:13) at Socket.emit (events.js:188:7) at readableAddChunk (_stream_readable.js:176:18) at Socket.Readable.push (_stream_readable.js:134:10) at TCP.onread (net.js:548:20) 

rethrownError.stack包含兴趣点(堆栈中的第一行),但其他所有内容都是垃圾:

 Error: ER_KEY_COLUMN_DOES_NOT_EXITS: Key column 'NonExisting' doesn't exist in table at sequelize.sync.catch (...\app.js:59:17) at tryCatcher (...\node_modules\bluebird\js\release\util.js:16:23) at Promise._settlePromiseFromHandler (...\node_modules\bluebird\js\release\promise.js:504:31) at Promise._settlePromise (...\node_modules\bluebird\js\release\promise.js:561:18) at Promise._settlePromise0 (...\node_modules\bluebird\js\release\promise.js:606:10) at Promise._settlePromises (...\node_modules\bluebird\js\release\promise.js:681:18) at Async._drainQueue (...\node_modules\bluebird\js\release\async.js:138:16) at Async._drainQueues (...\node_modules\bluebird\js\release\async.js:148:10) at Immediate.Async.drainQueues (...\node_modules\bluebird\js\release\async.js:17:14) at runCallback (timers.js:637:20) at tryOnImmediate (timers.js:610:5) at processImmediate [as _immediateCallback] (timers.js:582:5) 

我想保留关于它们两者的信息 – 并指定它们之间的链接,而不仅仅是作为两个不相关的日志条目添加。

我一直在考虑将它们logging为连接栈的单个错误, rethrownError.stack += '\n' + originalError.stack

这两个错误应该如何处理? 他们的堆栈痕迹应该join吗? 有没有约定在JavaScript中合并错误堆栈(特别是Node.js)?

其目的是保持结果的错误有意义,并且不会破坏parsing错误堆栈跟踪(即Stacktrace.js)的现有工具。

正在考虑的项目使用Winstonlogging器或简单的console.error ,所以错误在某个时候被string化(在上面的例子中,它是通过未处理的拒绝处理程序logging的)。

这是VError的一个轻量级替代方法: rerror (我是作者)

这个想法是一样的:包装错误的错误。 但是它更简单。 它具有较less的function,但也适用于浏览器。 它也考虑到创build堆栈跟踪是昂贵的。 而不是创build堆栈跟踪并将它们追加到string,它会在内部创build一堆错误,并且只在需要时才创build大堆栈跟踪(使用getter)。

 function fail() { throw new RError({ name: 'BAR', message: 'I messed up.' }) } function failFurther() { try { fail() } catch (err) { throw new RError({ name: 'FOO', message: 'Something went wrong.', cause: err }) } } try { failFurther() } catch (err) { console.error(err.why) console.error(err.stacks) } 

产量

 FOO: Something went wrong. <- BAR: I messed up. Error at failFurther (/Users/boris/Workspace/playground/es5/index.js:98:11) at Object.<anonymous> (/Users/boris/Workspace/playground/es5/index.js:107:3) at Module._compile (module.js:556:32) at Object.Module._extensions..js (module.js:565:10) at Module.load (module.js:473:32) at tryModuleLoad (module.js:432:12) at Function.Module._load (module.js:424:3) at Module.runMain (module.js:590:10) at run (bootstrap_node.js:394:7) <- Error at fail (/Users/boris/Workspace/playground/es5/index.js:88:9) at failFurther (/Users/boris/Workspace/playground/es5/index.js:96:5) at Object.<anonymous> (/Users/boris/Workspace/playground/es5/index.js:107:3) at Module._compile (module.js:556:32) at Object.Module._extensions..js (module.js:565:10) at Module.load (module.js:473:32) at tryModuleLoad (module.js:432:12) at Function.Module._load (module.js:424:3) at Module.runMain (module.js:590:10) 

build议阅读: https : //www.joyent.com/node-js/production/design/errors

据我所知,没有内置的方式来处理Node.js中的嵌套错误。 我唯一可以推荐的是使用VError库 。 处理高级error handling时,它非常有用。

您可以使用fullStack将多个错误的堆栈痕迹组合起来:

 var err1 = new VError('something bad happened'); var err2 = new VError(err1, 'something really bad happened here'); console.log(VError.fullStack(err2));