Node.js和x2B的错误处理原则;Express.js应用程序?
与其他框架相比,Node.js+应用程序中的错误报告/处理方式似乎有所不同。我的理解正确吗,它的工作原理如下 A)通过接收错误作为回调函数的参数来检测错误。例如: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); }
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的原作者)显然做到了这一点。它使用ES6yield
语句创建块,这些块看起来几乎同步,但以通常的节点异步方式处理:
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更新文档的链接。文章不错:但文本太多,示例太少。这是一篇面向真正专业人士的文章