NodeJS 7:如何在Async Mongoose Promises中显示正确的堆栈跟踪

当我在与bluebird mongoose承诺错误。 我没有正确的行号,这使我很难find错误。

 unknownFunction("A")#show me the correct line number in the trace async.timesSeries 100, (index, next) -> unknownFunction("B") #show me only the line number where I catch the error process.on 'uncaughtException', (err)-> console.log err.stack console.trace err throw err 

问题:如何获得正确的行号而不是错误被捕获的行号?

PS:我发现并尝试这个到目前为止: https : //github.com/groundwater/node-stackup但它给了我很多不相关的行号。

编辑:

这是我如何初步与蓝鸟mongoose:

 Promise = require("bluebird") Promise.config({ longStackTraces: true warnings: { wForgottenReturn: false } }) mongoose = require('mongoose') mongoose.Promise = Promise mongoose.set('error', true) 

示例正确:

在这里输入图像描述

  ReferenceError: unknownFunction is not defined - patient.update.js:267 

示例不正确:

在这里输入图像描述

 somepath/.tmp/serve/server.js:294 throw err; ^ ReferenceError: unknownFunction2 is not defined 

错误在patient.update.js第268行

Longjohn

随着longjohn

 somepath/node_modules/longjohn/dist/longjohn.js:192 throw e; ^ ReferenceError: unknownFunction2 is not defined 

叠起

这就是我所说的与node-stack-up无关的行(与unknownFunction2相同的testing):

  /somepath/myApp/.tmp/serve/server.js:296 throw err; ^ ReferenceError: unknownFunction2 is not defined ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:16 process.nextTick [myApp]/[async-listener]/index.js:16:26 - index.js:126 Kareem.execPost [myApp]/[kareem]/index.js:126:20 - index.js:251 [myApp]/[kareem]/index.js:251:15 - query.js:1616 [myApp]/[mongoose]/lib/query.js:1616:5 - document.js:317 model.Document.init [myApp]/[mongoose]/lib/document.js:317:5 - query.js:1609 completeOne [myApp]/[mongoose]/lib/query.js:1609:10 - query.js:1271 Immediate.<anonymous> [myApp]/[mongoose]/lib/query.js:1271:13 - utils.js:137 Immediate.<anonymous> [myApp]/[mquery]/lib/utils.js:137:16 - timers.js:649 runCallback timers.js:649:20 - timers.js:622 tryOnImmediate timers.js:622:5 - timers.js:594 processImmediate [as _immediateCallback] timers.js:594:5 ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:16 process.nextTick [myApp]/[async-listener]/index.js:16:26 - pool.js:454 handleOperationCallback [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:454:24 - pool.js:490 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:490:9 - pool.js:429 authenticateStragglers [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:429:16 - pool.js:463 Connection.messageHandler [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:463:5 - connection.js:309 Socket.<anonymous> [myApp]/[mongoose]/[mongodb-core]/lib/connection/connection.js:309: 22 - events.js:96 emitOne events.js:96:13 - events.js:188 Socket.emit events.js:188:7 - _stream_readable.js:176 readableAddChunk _stream_readable.js:176:18 - _stream_readable.js:134 Socket.Readable.push _stream_readable.js:134:10 - net.js:551 TCP.onread net.js:551:20 - glue.js:188 TCP.onread [myApp]/[async-listener]/glue.js:188:31 ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:88 Socket.connect [myApp]/[async-listener]/index.js:88:29 - net.js:74 Object.exports.connect.exports.createConnection net.js:74:35 - connection.js:389 Connection.connect [myApp]/[mongoose]/[mongodb-core]/lib/connection/connection.js:389: 11 - pool.js:1059 _createConnection [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1059:14 - pool.js:1151 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1151:13 - pool.js:1082 waitForAuth [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1082:39 - pool.js:1090 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1090:5 - pool.js:957 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:957:21 - glue.js:188 [myApp]/[async-listener]/glue.js:188:31 - next_tick.js:67 _combinedTickCallback internal/process/next_tick.js:67:7 - next_tick.js:98 process._tickCallback internal/process/next_tick.js:98:9 ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:16 process.nextTick [myApp]/[async-listener]/index.js:16:26 - pool.js:956 Pool.write [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:956:13 - cursor.js:288 CommandCursor.Cursor._find [myApp]/[mongoose]/[mongodb-core]/lib/cursor.js:288:22 - cursor.js:588 nextFunction [myApp]/[mongoose]/[mongodb-core]/lib/cursor.js:588:10 - cursor.js:696 CommandCursor.Cursor.next [as _next] [myApp]/[mongoose]/[mongodb-core]/lib/cursor.js:696:3 - cursor.js:849 fetchDocs [myApp]/[mongoose]/[mongodb]/lib/cursor.js:849:10 - cursor.js:876 toArray [myApp]/[mongoose]/[mongodb]/lib/cursor.js:876:3 - cursor.js:829 CommandCursor.Cursor.toArray [myApp]/[mongoose]/[mongodb]/lib/cursor.js:829:44 - db.js:1662 indexInformation [myApp]/[mongoose]/[mongodb]/lib/db.js:1662:39 - db.js:1626 Db.indexInformation [myApp]/[mongoose]/[mongodb]/lib/db.js:1626:44 - db.js:1129 ensureIndex [myApp]/[mongoose]/[mongodb]/lib/db.js:1129:8 - db.js:1105 Db.ensureIndex [myApp]/[mongoose]/[mongodb]/lib/db.js:1105:44 - collection.js:1891 ensureIndex [myApp]/[mongoose]/[mongodb]/lib/collection.js:1891:13 - collection.js:1879 Collection.ensureIndex [myApp]/[mongoose]/[mongodb]/lib/collection.js:1879:44 - collection.js:126 NativeCollection.(anonymous function) [as ensureIndex] [myApp]/[mongoose]/lib/drivers/node-mongodb-native/collection.js:12 6:28 - model.js:1019 create [myApp]/[mongoose]/lib/model.js:1019:22 - model.js:1033 Immediate.<anonymous> [myApp]/[mongoose]/lib/model.js:1033:7 - timers.js:649 runCallback timers.js:649:20 - timers.js:622 tryOnImmediate timers.js:622:5 - timers.js:594 processImmediate [as _immediateCallback] timers.js:594:5 ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:16 process.nextTick [myApp]/[async-listener]/index.js:16:26 - _stream_writable.js:377 onwrite _stream_writable.js:377:15 - _stream_writable.js:90 WritableState.onwrite _stream_writable.js:90:5 - net.js:724 Socket._writeGeneric net.js:724:5 - net.js:734 Socket._write net.js:734:8 - _stream_writable.js:334 doWrite _stream_writable.js:334:12 - _stream_writable.js:320 writeOrBuffer _stream_writable.js:320:5 - _stream_writable.js:247 Socket.Writable.write _stream_writable.js:247:11 - net.js:661 Socket.write net.js:661:40 - connection.js:500 Connection.write [myApp]/[mongoose]/[mongodb-core]/lib/connection/connection.js:500: 53 - pool.js:1137 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1137:26 - pool.js:1082 waitForAuth [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1082:39 - pool.js:1090 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:1090:5 - pool.js:957 [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:957:21 - glue.js:188 [myApp]/[async-listener]/glue.js:188:31 - next_tick.js:67 _combinedTickCallback internal/process/next_tick.js:67:7 - next_tick.js:98 process._tickCallback internal/process/next_tick.js:98:9 ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:16 process.nextTick [myApp]/[async-listener]/index.js:16:26 - pool.js:956 Pool.write [myApp]/[mongoose]/[mongodb-core]/lib/connection/pool.js:956:13 - cursor.js:288 Cursor._find [myApp]/[mongoose]/[mongodb-core]/lib/cursor.js:288:22 - cursor.js:588 nextFunction [myApp]/[mongoose]/[mongodb-core]/lib/cursor.js:588:10 - cursor.js:696 Cursor.next [as _next] [myApp]/[mongoose]/[mongodb-core]/lib/cursor.js:696:3 - cursor.js:672 nextObject [myApp]/[mongoose]/[mongodb]/lib/cursor.js:672:8 - cursor.js:262 Cursor.next [myApp]/[mongoose]/[mongodb]/lib/cursor.js:262:12 - collection.js:1401 findOne [myApp]/[mongoose]/[mongodb]/lib/collection.js:1401:10 - collection.js:1387 Collection.findOne [myApp]/[mongoose]/[mongodb]/lib/collection.js:1387:44 - collection.js:126 NativeCollection.(anonymous function) [as findOne] [myApp]/[mongoose]/lib/drivers/node-mongodb-native/collection.js:12 6:28 - node.js:38 NodeCollection.findOne [myApp]/[mquery]/lib/collection/node.js:38:19 - mquery.js:1787 model.Query.Query.findOne [myApp]/[mquery]/lib/mquery.js:1787:20 - query.js:1260 model.Query.Query._findOne [myApp]/[mongoose]/lib/query.js:1260:22 - index.js:239 [myApp]/[kareem]/index.js:239:8 - index.js:18 [myApp]/[kareem]/index.js:18:7 - glue.js:188 [myApp]/[async-listener]/glue.js:188:31 - next_tick.js:67 _combinedTickCallback internal/process/next_tick.js:67:7 - next_tick.js:98 process._tickCallback internal/process/next_tick.js:98:9 ---- async ---- - glue.js:150 asyncWrap [myApp]/[async-listener]/glue.js:150:28 - glue.js:401 wrapCallback [myApp]/[async-listener]/glue.js:401:35 - index.js:16 process.nextTick [myApp]/[async-listener]/index.js:16:26 - index.js:17 Kareem.execPre 

节点堆叠 , longjohn和Bluebird的长堆栈跟踪是可用的最佳解决scheme。 我不确定你的意思是“它给了我很多不相关的行号”。 这是给你一个堆栈跟踪,所以除非你已经编写了所有的代码,并且有零依赖关系,那么无论这个操作是否是asynchronous的,你都会看到函数对你没有写入的行进行调用。

基本上这些库所做的只是将分离的堆栈跟踪结合在一起。 通常情况下,JavaScript堆栈跟踪不会包含涉及asynchronous操作的任何内容,只包括最近的同步函数调用。 这些库猴子补丁可以引入asynchronous行为的大多数方法(process.nextTick,setTimeout,EventEmitter等)。 他们添加代码,在这些呼叫站点的每个呼叫站点上创build新的堆栈跟踪,并存储所有这些直到发生错误。 它会将所有已存储的堆栈跟踪结合在一起,以便实际上可以遍历所有asynchronous操作,直到到达原始调用站点。

您可以尝试下面的工具decofundebugging工具取消匿名函数。

在这个我写的下面的答案中提到的完整细节

线

文档如这里所述

对于任何uncaughtException服务器将停止,以便使服务器保持运行,即使有一个未捕获的exception我所做的是创build一个单独的集合用于存储错误,一旦未捕获的exception发生并返回时保存错误。

采集

 var ErrorSchema = new mongoose.Schema({ err_Message:{type:String}, err_Stack:{type:String}, date:{type:Date} }); 

调节器

 process.on('uncaughtException', function (err) { console.log(err); console.error((new Date).toUTCString() + ' uncaughtException:', err.message); console.error(err.stack); var newError = new Error; newError.err_Message = err.message; newError.err_Stack = err.stack; newError.date = moment(); newError.save(function(saveErr,errData){ if(!saveErr) console.log('New Error is saved'); else console.log('Error in saving error'); }); //process.exit(1) }); 

上述方法将未捕获的exception存储在Error集合中,并且进程/服务器不停止。

参考 :已经在生产中的Nodejsdebugging错误中得到解答

希望这可以帮助。

我错误的预感( https://github.com/petkaantonov/bluebird/issues/1297 )。

这个问题与nodejs没有关系,它是一个mongoosebug,它在一个更新的版本中被closureshttps://github.com/Automattic/mongoose/issues/4209 。 在旧版本中,似乎需要在mongoose查询结束时捕获错误。

解:

 PatientModel.findOne(newFilterUpdate).exec((err, patient) -> ... ).catch (err)-> console.log "err #{err}" 

或升级mongoose