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

时间:2016-12-08 14:25:01

标签: node.js asynchronous error-handling

unit Ex1; {$mode objfpc}{$H+} {$LinkLib GL} interface uses Classes, SysUtils, FileUtil, OpenGLContext, Forms, Controls, Graphics, gl, glu, Glut, Dialogs, ExtCtrls, LazOpenGLContext, LCLType; type { Tfrm } Tfrm = class(TForm) OpenGLControl1: TOpenGLControl; Timer: TTimer; procedure FormCreate(Sender: TObject); procedure TimerTimer(Sender: TObject); private { private declarations } public cube_rotation: GLFloat; Speed: Double; { public declarations } end; var frm: Tfrm; implementation {$R *.lfm} { Tfrm } procedure Tfrm.FormCreate(Sender: TObject); begin glClearColor(1.0, 1.0, 1.0, 1.0); // here brakepoint raised an exception class 'External:SIGSEGV' glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, double(width) / height, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0,-6.0); glRotatef(cube_rotation, 1.0, 1.0, 1.0); glBegin(GL_QUADS); glColor3f(0.0,1.0,0.0); glVertex3f( 1.0, 1.0,-1.0); glVertex3f(-1.0, 1.0,-1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); glEnd(); glBegin(GL_QUADS); glColor3f(1.0,0.5,0.0); glVertex3f( 1.0,-1.0, 1.0); glVertex3f(-1.0,-1.0, 1.0); glVertex3f(-1.0,-1.0,-1.0); glVertex3f( 1.0,-1.0,-1.0); glEnd(); glBegin(GL_QUADS); glColor3f(1.0,0.0,0.0); glVertex3f( 1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0,-1.0, 1.0); glVertex3f( 1.0,-1.0, 1.0); glEnd(); glBegin(GL_QUADS); glColor3f(1.0,1.0,0.0); glVertex3f( 1.0,-1.0,-1.0); glVertex3f(-1.0,-1.0,-1.0); glVertex3f(-1.0, 1.0,-1.0); glVertex3f( 1.0, 1.0,-1.0); glEnd(); glBegin(GL_QUADS); glColor3f(0.0,0.0,1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0,-1.0); glVertex3f(-1.0,-1.0,-1.0); glVertex3f(-1.0,-1.0, 1.0); glEnd(); glBegin(GL_QUADS); glColor3f(1.0,0.0,1.0); glVertex3f( 1.0, 1.0,-1.0); glVertex3f( 1.0, 1.0, 1.0); glVertex3f( 1.0,-1.0, 1.0); glVertex3f( 1.0,-1.0,-1.0); glEnd(); cube_rotation += 5.15 * Speed; OpenGLControl1.SwapBuffers; end; procedure Tfrm.TimerTimer(Sender: TObject); begin end; end. 承诺与mongoose时出现错误。我没有正确的行号,这使我很难找到错误。

bluebird

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

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

编辑:

这就是我用bluebird初学mongoose的方式:

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

示例正确:

enter image description here

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

示例错误:

enter image description here

  ReferenceError: unknownFunction is not defined

  - patient.update.js:267 

错误发生在somepath/.tmp/serve/server.js:294 throw err; ^ ReferenceError: unknownFunction2 is not defined 行nr 268

Longjohn

使用patient.update.js

longjohn

堆叠

这就是我对somepath/node_modules/longjohn/dist/longjohn.js:192 throw e; ^ ReferenceError: unknownFunction2 is not defined 无关行(与node-stack-up进行相同测试)的含义:

unknownFunction2

4 个答案:

答案 0 :(得分:3)

节点堆叠,longjohnBluebird's long stack traces是可用的最佳解决方案。我不确定你的意思是“它给了我很多不相关的行号。”它给你一个堆栈跟踪,所以除非你编写所有代码并且没有依赖关系,否则无论操作是否异步,你都必须看到对你没有写入的行的函数调用或不。

基本上这些库所做的只是将分离的堆栈跟踪拼接在一起。通常,JavaScript堆栈跟踪不包括涉及异步操作的任何内容,只包括最近的同步函数调用。这些库可以修补大多数可以引入异步行为的方法(process.nextTick,setTimeout,EventEmitter等)。它们添加代码,在每个调用站点创建一个新的堆栈跟踪,并存储所有这些,直到发生错误。它将所有存储的堆栈跟踪连接在一起,这样您就可以实际返回所有异步操作,直到到达原始调用站点。

答案 1 :(得分:0)

您可以尝试以下工具 decofun debug tool deanomise 匿名函数。

我在本

中写的以下答案中提到的完整详情
  

thread

文档如上所述here

答案 2 :(得分:0)

对于任何uncaughtException,服务器将停止以使服务器继续运行,即使存在未捕获的异常,我所做的是创建一个单独的集合来存储错误,一旦发生未捕获的异常并保存错误并返回。< / p>

<强>集合

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)
});

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

参考:已在Nodejs debug errors in production

中回答

希望这会有所帮助。

答案 3 :(得分:0)

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

此问题与nodejs无关,它是一个猫鼬错误,在较新版本https://github.com/Automattic/mongoose/issues/4209中关闭。在旧版本中,似乎需要在mongoose查询结束时捕获错误。

解决方案:

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

或升级mongoose