我开始使用 NodeJS 和 Express。来自其他流行脚本语言和 C++ 背景,异步调用 DB 函数有点陌生。我已经整理出一个模式,但我仍然对捕获异常感到好奇。以下是我的基本模式。
var callback = function(req, res) {
// do stuff
connection.query(queryString, function(err,result){
if (err) throw err;
// process results.
};
};
var express = require('express');
var app = express();
app.get('/', callback);
app.listen(3000,function() {
console.log('listening');
};
通常我有很多端点和回调。我有点迷失在哪里设置了 try/catch block 来捕获回调中抛出的错误。我四处寻找一些建议,但其中很多似乎都在正在使用的 Web 框架(如果有的话)上。
最佳答案
当您抛出异步回调时,异常只会返回到数据库事件处理程序的内部,并且您无法捕获或处理该异常。所以,基本上它没有任何好处。它只会导致您中止对该请求的处理,并且您永远不会对该请求发送响应。
基本上,您有多种处理错误的选择。您可以在每个端点中完全正确地处理它并发送某种错误响应。
在每个错误点发送响应
app.get('/', function(req, res) {
// do stuff
connection.query(queryString, function(err,result){
if (err) return res.status(500).send(someErrorResponse);
// process results.
};
});
转发到集中式错误处理程序
或者,您可以通过调用 next(err)
将错误转发到集中式错误处理程序:
app.get('/', function(req, res, next) {
// do stuff
connection.query(queryString, function(err,result){
// if error, forward it on to our centralized error handler
if (err) return next(err);
// process results.
};
});
// centralized error handler - note how it has four parameters
app.use(function(err, req, res, next) {
// formulate an error response here
console.log(err);
res.status(500).send(someErrorMessage)
});
参见Nodejs handle unsupported URLs and request types有关在 Express 中使用通用错误处理程序的方法的更多信息。
使用 promise 收集每个路由中的错误
如果您使用更多复杂的异步操作序列,其中可能有多个异步操作按顺序排列在一起,那么处理每个异步操作的错误确实会很痛苦。在这里,对所有异步操作使用 Promise 可以更轻松地允许所有错误渗透到每个路由顶层的一个 .catch()
语句。您没有说明您正在使用什么数据库,但这里有一个大概的想法。总体思路是,您可以编写代码,以便所有 Promise 拒绝(例如错误)都将传播到每个路由处理程序中的一个中心 .catch()
,然后您可以调用 next( err)
来自 .catch()
,将错误发送到集中式错误处理程序。以下是如何通过一个数据库操作查找最新版本的 Mongoose(您没有说您正在使用哪个数据库)。
app.get('/', function(req, res, next) {
// do stuff
connection.query(queryString).exec().then(function(result){
// process results.
}).catch(next);
});
// centralized error handler - note how it has four parameters
app.use(function(err, req, res, next) {
// formulate an error response here
console.log(err);
res.status(500).send(someErrorMessage)
});
而且,如果您有多个操作,情况如下:
app.get('/', function(req, res, next) {
// do stuff
connection.query(queryString).exec().then(function(result){
// process results, then make another query
// return the promise from this second operaton so both results
// and error are chained to the first promise
return connection.query(...).exec();
}).then(function(result) {
// process chained result
}).catch(next);
});
// centralized error handler - note how it has four parameters
app.use(function(err, req, res, next) {
// formulate an error response here
console.log(err);
res.status(500).send(someErrorMessage)
});
由于 ES6 内置了对 Promise 的支持,并且 ES7 将添加对异步操作的 async/await 支持(基于 Promise),并且所有提供异步操作的重要库都已添加或正在添加对 Promise 的支持,因此很明显Promise 是管理异步操作的语言的 future 。这将是我强烈的建议。
关于node.js - NodeJS 捕获错误的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42611707/