node.js - NodeJS 捕获错误的最佳实践

标签 node.js express error-handling

我开始使用 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/

相关文章:

ios - 如何向具有用户身份验证的网站发出访问其内容的请求?

node.js - 如何在Windows Azure上部署socket.io Node.js应用程序?

node.js - 有什么方法可以检查NodeJS中的TCP套接字是否已连接

exception - 如何处理jbpm工作流程中的错误或异常

javascript - 删除 react 17.0.2 中的自动前缀警告

node.js - 当用户点击不同的url时,nodejs + express自动重定向

node.js - expressJs 标题变量声明的默认值

php - php中错误处理的正确方法

c# - 在 C# 中检查打印机状态?

node.js - 即使有更多行,Typeahead 也仅显示 1 行