繁体   English   中英

在mocha中测试nodeJS时,域没有正确捕获错误

[英]Domains not properly catching errors while testing nodeJS in mocha

当运行利用域进行错误处理的测试时,即使库中的域处理程序应该捕获错误,Mocha仍然会抛出错误。 如果我在Mocha之外执行代码,它的功能正常导致我相信问题是Mocha。

例:

foo.js

module.exports = function(done) {
    var domain = require("domain");
    var d = domain.create();

    d.on("error", function() {
        done();
    });

    d.run(function() {
        throw new Error("foo");
    });
}

test.js -错误内抛出foo.js没有被域捕获。

describe("test", function() {
    it("should succeed", function(done) {
        var foo = require("./foo.js");
        foo(function() {
            console.log("done");
            done();
        });
    });
});

result : error thrown

script.js - 域正确捕获错误并冒泡。

var foo = require("./foo.js");
foo(function() {
    console.log("done");
});
result : done

正如您在上面所看到的,如果我直接指向script.js它会按照需要运行,域处理程序会捕获错误并继续执行代码。 如果我在Mocha测试中运行相同的代码块,则错误将暂停测试并给出失败。 我相信这是因为错误是在uncaughtException处理程序或类似的东西上发送的。 另一个复杂因素是它在Mocha中正常工作,如果我在函数调用周围有一个process.nextTick(),让我相信Mocha只能处理同步错误,但对异步错误工作得很好。

这里有一些关于这个问题的讨论: https//groups.google.com/forum/#! msg / nodejs /n- W9BSfxCjI / SElI1DJ_6u0Jhttps://github.com/joyent/node/issues/4375

我的困惑是,所有这些讨论似乎都表明问题已在几个月前得到解决。 任何人都知道这个问题的简单解决方法,或者为什么我没有看到其他人似乎相信的错误已修复此时此问题。

我在Windows 7上的CentOS 6.3 Vagrant VirtualBox上运行节点v0.10.18和Mocha 1.13.0。

发现了问题。 NodeJS域捕获同步错误,但事件继续冒泡到try / catch 如果在try/catch包装domain.run() ,则将执行域错误处理程序和catch。

因此,似乎最好的做法是在所有domain.run()使用process.nextTick。 这在文档示例中显示,但未按我的意愿明确表达。

例:

d.run(function() {
    process.nextTick(function() {
        // do stuff
    });
});

在这种情况下,缺陷不在摩卡。

在try / catch中没有捕获同步错误的NodeJS域的证明: https//gist.github.com/owenallenaz/7141699

nodejs域肯定会捕获同步错误

看看这个简单的测试案例

var domain = require("domain");
var d = domain.create();

d.on("error", function() {
    console.log("domain caught");
});


d.run(function() {
    throw new Error("foo");
});


// result: domain caught

编辑 :自写这个答案以来,我写了一篇博客文章,描述了域名发生了什么,并尝试捕获,以及是否可以使用域名作为try catch的批发替代品。 它总结了这里讨论的大部分内容。

http://www.lighthouselogic.com/node-domains-as-a-replacement-for-try-catch/

原始答案:

实际上Mocha存在问题。

我写了以下测试函数:

function error(callback){
     var d = domain.create().on('error', function(err){
        console.log("Caught Error in Domain Handler")
        return callback(err);
    });
    d.enter();
    throw new Error("TestError");
    d.exit();
}

然后我写了一个没有mocha的简单测试:

error(function(err){
    if(err)
    {
        console.log("Error was returned");
    }else
    {
        console.log("Error was not returned")
    }
})

我收到的输出是:

Caught Error in Domain Handler
Error was returned

当我使用Mocha测试时:

describe('Domain Tests', function(){
    it('Should return an error when testing', function(done){
        error(function(err){
            if(err)
            {
                console.log("Error was returned");
            }else
            {
                console.log("Error was not returned")
            }
            return done();
        })
    });
});

我收到了以下输出:

․

  0 passing (4ms)
  1 failing

  1) Domain Tests Should return an error when testing:
     Error: TestError
      at error (/Users/bensudbury/Documents/node_projects/testMochaDomains/test.js:9:11)
      at Context.<anonymous> (/Users/bensudbury/Documents/node_projects/testMochaDomains/testMocha.js:6:3)
      at Test.Runnable.run (/usr/local/share/npm/lib/node_modules/mocha/lib/runnable.js:194:15)
      at Runner.runTest (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:358:10)
      at /usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:404:12
      at next (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:284:14)
      at /usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:293:7
      at next (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:237:23)
      at Object._onImmediate (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:261:5)
      at processImmediate [as _immediateCallback] (timers.js:330:15)

如您所见:域错误处理程序被短路了。

此问题似乎与以下问题有关:

https://github.com/visionmedia/mocha/issues/513

虽然Node问题已经关闭,但mocha中的问题仍然存在。

建议的解决方法: https//gist.github.com/mcollina/4443963在这种情况下无法解决问题。

我挖掘了Mocha的代码并发现问题的出现是因为mocha将测试包装在try catch块中。 这意味着异常被捕获并且永远不会发送到uncaughtException或_fatalException处理程序,具体取决于您使用的节点的版本。

您的解决方法很好,但nodejs域肯定会捕获同步错误,因此我不会更改您的代码,而是更改您的测试。 您的新测试应如下所示:

describe("test", function() {
    it("should succeed", function(done) {
        process.nextTick(function(){
            var foo = require("./foo.js");
            foo(function() {
                console.log("done");
                done();
            });
        })      
    });
});

我没有测试过这段代码,但我的示例的类似代码正常工作:

it('Should return an error when testing', function(done){   
    process.nextTick(function(){
        error(function(err){
            if(err)
            {
                console.log("Error was returned");
            }else
            {
                console.log("Error was not returned")
            }
            return done();
        });
    })
});

我在Mocha的问题结尾添加了一条评论,看看是否可以解决:

https://github.com/visionmedia/mocha/issues/513

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM