如果db调用抛出错误,如何返回错误标头?

时间:2013-12-03 17:33:56

标签: node.js express couchbase

我有一个使用NodeJS和Couchbase运行的小型数据收集网络应用程序。要求是,当第三方向我们推送一些数据并且我们能够处理它时,我们返回200头,但如果存储该数据有任何问题,我们返回500.这意味着他们可以重新尝试使用失败的数据批处理。

我遇到的问题是总是返回200(因为DB调用是异步完成的)。这是一个例子:

...
var app = express();

function create(req, res) {

    var error = false;

    // Parse all the entries in request
    for (var i = 0; i < req.body.length; i++) {
        var event = req.body[i];

        if (!event.email) {
            // log error to file
            error = true;
            res.send("Event object does not have an email address!", 500);
        }

        // Greate the id index value
        var event_id = 'blah';

        // See if record already exists
        db.get(event_id, function (err, result) {

            var doc = result.value;
            if (doc === undefined) {
                // Add a new record
                db.add(event_id, event, function (err, result) {
                    if (err) {
                        error = true;
                        res.send('There were processing errors', 500);
                    }
                });
            }
        });
    }

    if (error)
        res.send("Try again", 500);
    else
        res.send("OK", 200);
}
app.post('/create', create);

有没有办法让应用程序等待那些数据库调用完成,即这个功能是否同步?或者我是否使用了错误的技术? :(

我决定使用NodeJS + Couchbase,因为我们可能会有非常多的调用,其中必须写入,读取和删除数据(小JSON对象)。编辑:啊,数据结构可能会因各种事件而发生变化,因此能够存储非均匀形状的文档具有很大的优势!

1 个答案:

答案 0 :(得分:2)

这是async library的一个典型用例,它是一个实用带库,有很多模式可以处理异步函数。

由于您需要为每条记录调用异步函数,因此可以使用async.each,它为数组的所有元素执行异步函数。所有异步任务完成后,将调用最后一个回调。

var app = express();

function handleEvent = function (event, callback) {
    if (! event.email) {
        callback(new Error('Event object does not have an email address!'));
    }
    var event_id = 'blah';
    db.get(event_id, function (err, result) {
        var doc = result.value;
        if (doc === undefined) {
            // Add a new record
            db.add(event_id, event, function (err, result) {
                if (err) {
                    callback(new Error('There were processing errors'));
                }
                else {
                    callback(null);
                }
            });
        }
    });
}

function create(req, res) {
    // https://github.com/caolan/async#each
    async.each(req.body, handleEvent, function (err) {
        if (err)
            res.send(err.message, 500);
        else
            res.send('OK', 200);
    });
}