Node.js和x2B的错误处理原则;Express.js应用程序?

Node.js和x2B的错误处理原则;Express.js应用程序?,node.js,express,Node.js,Express,与其他框架相比,Node.js+应用程序中的错误报告/处理方式似乎有所不同。我的理解正确吗,它的工作原理如下 A)通过接收错误作为回调函数的参数来检测错误。例如: doSomethingAndRunCallback(function(err) { if(err) { … } }); B)通过调用next(err)报告中间件中的错误。例如: handleRequest(req, res, next) { // An error occurs… next(err); }

与其他框架相比,Node.js+应用程序中的错误报告/处理方式似乎有所不同。我的理解正确吗,它的工作原理如下

A)通过接收错误作为回调函数的参数来检测错误。例如:

doSomethingAndRunCallback(function(err) { 
    if(err) { … }
});
B)通过调用next(err)报告中间件中的错误。例如:

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}
app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});
app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});
C)通过抛出错误来报告路由中的错误。例如:

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}
app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});
app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});
D)通过app.error()配置自己的错误处理程序或使用通用连接错误处理程序来处理错误。例如:

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}
app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});
app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});

这四条原则是Node.js+Express.js应用程序中所有错误处理/报告的基础吗?

Node.js中的错误处理通常采用A)格式。大多数回调都会返回一个错误对象作为第一个参数或
null

js使用中间件,中间件语法使用B)和E)(如下所述)

C) 如果你问我的话,这是个坏习惯

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});
您可以很容易地将上述内容重写为

app.get('/home', function(req, res, next) {
    // An error occurs
    next(err);
});
中间件语法在
get
请求中有效

至于(D)

tjholowaychuk:app.error在3.x中被删除

TJ刚刚确认,
app.error
被弃用,取而代之的是E

(E)


任何长度为4(4个参数)的中间件都被视为错误中间件。当你调用
next(err)
connect去调用基于错误的中间件。

Joyent的人已经发表了这篇文章。这是Node.js开发者必读的文章。

为什么选择第一个参数? 由于Node.js的异步特性,作为err模式的第一个参数已经作为一种约定得到了很好的确立。这是因为异步:

try {
    setTimeout(function() {
        throw 'something broke' //Some random error
    }, 5)
}
catch(e) {
   //Will never get caught
}
因此,拥有回调的第一个参数几乎是异步传递错误的唯一明智方法,而不仅仅是抛出错误

这样做将导致一个
未处理的异常
,从听起来的方式来看,这意味着没有采取任何措施使应用程序摆脱混乱状态

例外,为什么会存在 但是,值得注意的是,Node.js的几乎所有部分都是事件发射器,引发异常是一个低级事件,可以像处理所有事件一样进行处理:

//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
    console.error("calm down...", err)
});
可以但不应该被带到极端,使应用程序尽最大努力永不崩溃。这在几乎每个用例中都是一个糟糕的想法,因为它会让开发人员对应用程序状态中发生的事情一无所知,这类似于在try-catch中包装main

域-逻辑分组事件 作为处理导致应用程序崩溃的异常问题的一部分,允许开发人员以Express.js应用程序为例,尝试在发生灾难性故障时明智地关闭连接

ES6 可能需要提到的是,这将再次发生变化,因为ES6允许生成器模式创建仍然可以通过try/catch块捕获的异步事件

Koa(作者TJ Holowaychuck,Express.js的原作者)显然做到了这一点。它使用ES6
yield
语句创建块,这些块看起来几乎同步,但以通常的节点异步方式处理:

app.use(function *(next) {
    try {
        yield next;
    } 
    catch (err) {
        this.status = err.status || 500;
        this.body = err.message;
        this.app.emit('error', err, this);
    }
});

app.use(function *(next) {
    throw new Error('some error');
})

此示例被无耻地从中窃取。

谢谢!对于将来可能遇到这种情况的任何人来说,“方法e”的参数顺序似乎实际上是err,req,res,next(而不是req,res,next,err)。因此这看起来很好,但我看到的一个问题是,一些错误永远不会到达您描述的错误处理程序,只能被进程捕获。on('uncaughtException',fn)处理程序。传统智慧是让这种情况发生,并依靠Forever或类似的方法重新启动应用程序,但如果你这样做,你如何返回友好的错误页面?@chovy,也只是一个供参考的。错误处理程序必须在抛出/下一个错误后提供给应用程序。如果是在之前,它将不会捕获错误。下一步(err)本质上是Express版本的抛出错误,您必须在自己的中间件中显式地调用它though@qodeninja这种方法被认为是Express中的最佳实践。很棒的文章,修复了指向Joyent更新文档的链接。文章不错:但文本太多,示例太少。这是一篇面向真正专业人士的文章