我正在使用bluebird promise ,以及 Sequelize (内部也使用 bluebird)在 Node 上。
一开始我就这样做:
// only use one Promise library for the entire application
GLOBAL.Promise = Sequelize.Promise || require('bluebird');
// setup long stack traces
GLOBAL.Promise.longStackTraces();
大多数时候,我都能得到很好的堆栈跟踪。但有时当我从 Sequelize 的底层 MySQL 实现中收到错误时,堆栈跟踪就会出错,如下所示:
SequelizeUniqueConstraintError
at module.exports.Query.formatError (D:\code\theapp\node_modules\sequelize\lib\dialects\mysql\query.js:109:16)
at Query._callback (D:\code\theapp\node_modules\sequelize\lib\dialects\mysql\query.js:38:23)
at Query.Sequence.end (D:\code\theapp\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
at Query.ErrorPacket (D:\code\theapp\node_modules\mysql\lib\protocol\sequences\Query.js:93:8)
at Protocol._parsePacket (D:\code\theapp\node_modules\mysql\lib\protocol\Protocol.js:271:23)
at Parser.write (D:\code\theapp\node_modules\mysql\lib\protocol\Parser.js:77:12)
at Protocol.write (D:\code\theapp\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous (D:\code\theapp\node_modules\mysql\lib\Connection.js:82:28)
at Socket.emit (events.js:95:17)
at Socket.<anonymous (_stream_readable.js:764:14)
at Socket.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:426:10)
at emitReadable (_stream_readable.js:422:5)
at readableAddChunk (_stream_readable.js:165:9)
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event:
From previous event: (D:/code/theapp/components/util/Log.js:116)
我在 Windows 7 上运行 Node v0.10.33。
这是一个错误吗?如果是这样,我应该使用哪个库(或 Node?)来归档它?
最佳答案
我做了一些更多的挖掘,发现这个特定的错误是一个自定义的 Sequelize 错误,它在它的构造函数中调用进一步的自定义错误构造函数,一直到 Error.apply(this, arguments)
。该错误也包含了原始错误。如果我获得 native 错误(不是通过 Error.apply
创建的)而不是包装器,即使我只读取一次(如 var smth = err.theWrappedError && err.theWrappedError.something;
),也会出现正确的堆栈跟踪。所以我认为,就像之前的堆栈跟踪之谜一样,这可能是一个 V8 错误。
仅供引用,此代码导致了上述错误的堆栈跟踪:
if (!message) {
message = 'exception';
}
console.error(message = this.Tools.formatUserMessage((message && (message + ' - ') || '')));
console.error(err.stack);
此代码显示了更多信息和正确的堆栈跟踪:
var parent = err.parent; // access the underlying error here
var sql = (parent && parent.sql) || err.sql;
var sqlMessage = sql && 'SQL error `' + sql + ']';
if (!message) {
if (sql) {
message = sqlMessage;
}
else {
message = 'exception';
}
}
else {
message += ' - ' + sqlMessage;
}
console.error(message = this.Tools.formatUserMessage((message && (message + ' - ') || '')));
console.error(err.stack);
parent && parent.stack && console.error(parent.stack);
有两件事:
- 最终,您可能希望使其完全递归并继续向上,只要还有另一个
parent
,尽管我还没有看到超过两个的错误链。 - 尽管
err.stack
将揭示正确的错误跟踪,展示全部内容也没什么坏处。
第二个代码片段的堆栈跟踪示例:
[2015-01-30 17:09:13.235] [ERROR] default - [asd] SQL error (`INSERT INTO `theApp_user` (`uid`,`role`,`displayRole`,`name`,`locale`,`createdAt`,`updatedAt`) VALUES (DEFAULT,4,4,'asd','en','20109:13','2015-01-30 09:09:13');`) - (D:/code/theApp/components/util/Log.js:126)
[2015-01-30 17:09:13.237] [ERROR] default - SequelizeUniqueConstraintError
at module.exports.Query.formatError (D:\code\theApp\node_modules\sequelize\lib\dialects\mysql\query.js:109:16)
at Query._callback (D:\code\theApp\node_modules\sequelize\lib\dialects\mysql\query.js:38:23)
at Query.Sequence.end (D:\code\theApp\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
at Query.ErrorPacket (D:\code\theApp\node_modules\mysql\lib\protocol\sequences\Query.js:93:8)
at Protocol._parsePacket (D:\code\theApp\node_modules\mysql\lib\protocol\Protocol.js:271:23)
at Parser.write (D:\code\theApp\node_modules\mysql\lib\protocol\Parser.js:77:12)
at Protocol.write (D:\code\theApp\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (D:\code\theApp\node_modules\mysql\lib\Connection.js:82:28)
at Socket.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:764:14)
at Socket.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:426:10)
at emitReadable (_stream_readable.js:422:5)
at readableAddChunk (_stream_readable.js:165:9)
From previous event:
at new Promise (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:84:37)
at new SequelizePromise (D:\code\theApp\node_modules\sequelize\lib\promise.js:28:17)
at module.exports.Query.run (D:\code\theApp\node_modules\sequelize\lib\dialects\mysql\query.js:31:19)
at D:\code\theApp\node_modules\sequelize\lib\sequelize.js:613:20
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18)
at process._tickDomainCallback (node.js:463:13)
From previous event:
at new Promise (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:84:37)
at new SequelizePromise (D:\code\theApp\node_modules\sequelize\lib\promise.js:28:17)
at ConnectionManager.getConnection (D:\code\theApp\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:186:10)
at module.exports.Sequelize.query (D:\code\theApp\node_modules\sequelize\lib\sequelize.js:610:85)
at module.exports.QueryInterface.insert (D:\code\theApp\node_modules\sequelize\lib\query-interface.js:451:27)
at D:\code\theApp\node_modules\sequelize\lib\instance.js:601:43
From previous event:
at D:\code\theApp\node_modules\sequelize\lib\instance.js:578:25
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18)
at process._tickDomainCallback (node.js:463:13)
From previous event:
at module.exports.Instance.save (D:\code\theApp\node_modules\sequelize\lib\instance.js:500:23)
at module.exports.Model.create (D:\code\theApp\node_modules\sequelize\lib\model.js:1051:8)
at Object.Private.createAndLogin (D:\code\theApp\components\models\core\User.js:339:38)
at Object.<anonymous> (D:\code\theApp\components\debug\CourseSimulator.js:440:55)
From previous event:
at Object.<anonymous> (D:\code\theApp\components\debug\CourseSimulator.js:415:47)
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18)
From previous event:
at Promise$bind [as bind] (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:104:9)
at Object.Public.reset (D:\code\theApp\components\debug\CourseSimulator.js:390:22)
at D:\code\theApp\node_modules\nogap\lib\CommandProxy.js:129:74
at tryCatcher (D:\code\theApp\node_modules\nogap\assets\bluebird.js:4408:31)
at Promise._settlePromiseFromHandler (D:\code\theApp\node_modules\nogap\assets\bluebird.js:2342:31)
at Promise._settlePromiseAt (D:\code\theApp\node_modules\nogap\assets\bluebird.js:2504:18)
at Promise._settlePromiseAtPostResolution (D:\code\theApp\node_modules\nogap\assets\bluebird.js:2070:10)
at Async._drainQueue (D:\code\theApp\node_modules\nogap\assets\bluebird.js:152:12)
at Async._drainQueues (D:\code\theApp\node_modules\nogap\assets\bluebird.js:157:10)
at Async.drainQueues (D:\code\theApp\node_modules\nogap\assets\bluebird.js:82:14)
at process._tickDomainCallback (node.js:463:13)
From previous event:
at new Promise (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:84:37)
at new SequelizePromise (D:\code\theApp\node_modules\sequelize\lib\promise.js:28:17)
at ConnectionManager.releaseConnection (D:\code\theApp\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:196:10)
at D:\code\theApp\node_modules\sequelize\lib\sequelize.js:615:39
at Object.finallyHandler (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\finally.js:64:23)
From previous event:
at new Promise (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:84:37)
at new SequelizePromise (D:\code\theApp\node_modules\sequelize\lib\promise.js:28:17)
at module.exports.Query.run (D:\code\theApp\node_modules\sequelize\lib\dialects\mysql\query.js:31:19)
at D:\code\theApp\node_modules\sequelize\lib\sequelize.js:613:20
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18)
at process._tickDomainCallback (node.js:463:13)
From previous event:
at new Promise (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:84:37)
at new SequelizePromise (D:\code\theApp\node_modules\sequelize\lib\promise.js:28:17)
at ConnectionManager.getConnection (D:\code\theApp\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:186:10)
at module.exports.Sequelize.query (D:\code\theApp\node_modules\sequelize\lib\sequelize.js:610:85)
at module.exports.QueryInterface.insert (D:\code\theApp\node_modules\sequelize\lib\query-interface.js:451:27)
at D:\code\theApp\node_modules\sequelize\lib\instance.js:601:43
From previous event:
at D:\code\theApp\node_modules\sequelize\lib\instance.js:578:25
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18)
at process._tickDomainCallback (node.js:463:13)
From previous event:
at module.exports.Instance.save (D:\code\theApp\node_modules\sequelize\lib\instance.js:500:23)
at module.exports.Model.create (D:\code\theApp\node_modules\sequelize\lib\model.js:1051:8)
at Object.Private.createAndLogin (D:\code\theApp\components\models\core\User.js:339:38)
at Object.<anonymous> (D:\code\theApp\components\debug\CourseSimulator.js:440:55)
From previous event:
at Object.<anonymous> (D:\code\theApp\components\debug\CourseSimulator.js:415:47)
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18)
From previous event:
at Promise$bind [as bind] (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:104:9)
at Object.Public.reset (D:\code\theApp\components\debug\CourseSimulator.js:390:22)
at D:\code\theApp\node_modules\nogap\lib\CommandProxy.js:129:74
at tryCatcher (D:\code\theApp\node_modules\nogap\assets\bluebird.js:4408:31)
at Promise._settlePromiseFromHandler (D:\code\theApp\node_modules\nogap\assets\bluebird.js:2342:31)
at Promise._settlePromiseAt (D:\code\theApp\node_modules\nogap\assets\bluebird.js:2504:18)
at Promise._settlePromiseAtPostResolution (D:\code\theApp\node_modules\nogap\assets\bluebird.js:2070:10)
at Async._drainQueue (D:\code\theApp\node_modules\nogap\assets\bluebird.js:152:12)
at Async._drainQueues (D:\code\theApp\node_modules\nogap\assets\bluebird.js:157:10)
at Async.drainQueues (D:\code\theApp\node_modules\nogap\assets\bluebird.js:82:14)
at process._tickDomainCallback (node.js:463:13) (D:/code/theApp/components/util/Log.js:127)
[2015-01-30 17:09:13.240] [ERROR] default - Error: ER_DUP_ENTRY: Duplicate entry 'asd' for key 'theApp_user_name'
at Query.Sequence._packetToError (D:\code\theApp\node_modules\mysql\lib\protocol\sequences\Sequence.js:48:14)
at Query.ErrorPacket (D:\code\theApp\node_modules\mysql\lib\protocol\sequences\Query.js:82:18)
at Protocol._parsePacket (D:\code\theApp\node_modules\mysql\lib\protocol\Protocol.js:271:23)
at Parser.write (D:\code\theApp\node_modules\mysql\lib\protocol\Parser.js:77:12)
at Protocol.write (D:\code\theApp\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (D:\code\theApp\node_modules\mysql\lib\Connection.js:82:28)
at Socket.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:764:14)
at Socket.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:426:10)
at emitReadable (_stream_readable.js:422:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:528:21)
--------------------
at Protocol._enqueue (D:\code\theApp\node_modules\mysql\lib\protocol\Protocol.js:135:48)
at Connection.query (D:\code\theApp\node_modules\mysql\lib\Connection.js:185:25)
at D:\code\theApp\node_modules\sequelize\lib\dialects\mysql\query.js:32:23
at sequelizeResolver (D:\code\theApp\node_modules\sequelize\lib\promise.js:32:12)
at tryCatch2 (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\util.js:53:21)
at Promise$_resolveFromResolver [as _resolveFromResolver] (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:618:13)
at new Promise (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:84:37)
at new SequelizePromise (D:\code\theApp\node_modules\sequelize\lib\promise.js:28:17)
at module.exports.Query.run (D:\code\theApp\node_modules\sequelize\lib\dialects\mysql\query.js:31:19)
at D:\code\theApp\node_modules\sequelize\lib\sequelize.js:613:20
at tryCatch1 (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\util.js:45:21)
at Promise$_callHandler [as _callHandler] (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:660:13)
at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:675:18)
at Promise$_settlePromiseAt (D:\code\theApp\node_modules\sequelize\node_modules\bluebird\js\main\promise.js:845:14)
at Promise._settlePromiseAt (D:\code\theApp\node_modules\sequelize\lib\promise.js:66:18) (D:/code/theApp/components/util/Log.js:128)
更新
实际上,我发现这个有时有效,有时无效,有时部分有效(显示部分堆栈跟踪)...可能是 V8 堆栈或堆管理器中的竞争条件...
关于javascript - Bluebird 在与 Sequelize/MySQL 一起使用时显示损坏的堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28231970/