Mongo db与Monk的连接:如果db关闭,则错误捕获和处理 [英] Mongo db with Monk: error catching and handling if db is down

查看:118
本文介绍了Mongo db与Monk的连接:如果db关闭,则错误捕获和处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Mongo的新手.我需要一个简单项目的数据库,并最终完成了将Mongo与Monk结合使用的教程,但是我在理解如何处理错误方面遇到问题.

I'm new to Mongo. I needed a database for a simple project and ended up following a tutorial using Mongo with Monk but I have problems understanding how to handle errors.

背景:我在客户端有一张注册表.当用户单击一个按钮时,数据通过AJAX发送到控制器,该控制器(通过验证,但现在不相关)将这些数据插入数据库,然后发送成功或错误信息.当数据库启动时,一切似乎都正常.

Background: I have a registration form on the client side. When the user clicks a button, the data is sent via AJAX to the controller that (upon validation, but this is not relevant now) inserts such data into the database and sends back either success or error. When the db is up all seems to work fine.

问题:如果我没有启动数据库并尝试发送请求,则不会返回任何错误.根本没有任何反应.在控制台上一段时间后,我得到: POST/members/addmember--ms--.

The problem: If I don't start the db and try to send the request anyway, no error is returned. Simply nothing happens. After some time on the console I get: POST /members/addmember - - ms - -.

在这种情况下,我认为应该向用户返回一些错误,那么我该怎么做?

I think some error should be returned to the user in this case, so how could I do this?

下面是发帖请求(与本教程中的请求差不多):

The post request is below (pretty much as from the tutorial):

// app.js 

var db = monk('localhost:27017/dbname')
[...]
// I realize it might be not optimal here
app.use(function(req,res,next){ 
    req.db = db;
    next();
});

// members.js

router.post('/addmember', function(req, res) {
  var db = req.db;
  var collection = db.get('memberstest');
  collection.insert(req.body, function(err, result){
    res.json(
      (err === null) ? { msg: 'success' } : { msg: err }
    );
  });
});

如果数据库关闭,我想问题实际上甚至早于插入操作,那就是那个" db.get()".那么如何检查 get 是否可以实际完成?我想,鉴于节点的异步特性,像try/catch这样的东西在这里将毫无意义.正确吗?

If the db is down I guess the problem is actually even earlier than the insert, that is in that "db.get()". So how to check if that get can actually be done? I suppose that given the asynchronous nature of node something like a try/catch would be pointless here. Correct?

在尼尔的回答和一些尝试之后,我整理了以下似乎可以完成工作的内容.但是,鉴于我对此缺乏信心,如果下面的代码行得通,因为有道理或偶然,我将不胜感激.我添加了bufferMaxEntries:0选项,并如下修改了控制器.在ajax回调中,我现在只有一个警报,该警报显示抛出的错误消息(如果有的话).

After Neil's answer and a bit of trying, I put together the following that seems to do the job. However, given my scarce degree of confidence on this, I'd appreciate a comment if the code below works because it makes sense or by chance. I added the bufferMaxEntries: 0 options and modified the controller as follows. In the ajax callback I simply have an alert for now that shows the error message thrown (if any).

router.post('/addmember', async (req,res) => {

    try {
      let db = req.db;
      let collection = db.get('memberstest');

      collection.insert(req.body, function(err, result){
      res.json(
        (err === null) ? { msg: 'success' } : { msg: err }
      );
    });

    await db.then(() => 1);

    } catch(e) {
      res.json({msg: e.message})
    }

});

推荐答案

实际上您可以设置bufferMaxEntries选项(在

Well you can actually set the bufferMaxEntries option ( documented under Db but deprecated for that object usage, use at "top level as demonstrated instead" ) on the connection, which essentially stops "queuing" requests on the driver when no connection is actually present.

作为一个最小的例子:

index.js

const express = require('express'),
      morgan = require('morgan'),
      db = require('monk')('localhost/test',{ bufferMaxEntries: 0 }),
      app = express();

const routes = require('./routes');

app.use(morgan('combined'));

app.use((req,res,next) => {
  req.db = db;
  next();
});

app.use('/', routes);

(async function() {

  try {

    await db.then(() => 1);

    let collection = db.get('test');
    await collection.remove({});

    await collection.insert(Array(5).fill(1).map((e,i) => ({ a: i+1 })));
    console.log('inserted test data');

    await app.listen(3000,'0.0.0.0');
    console.log('App waiting');

  } catch(e) {
    console.error(e);
  }

})();

routes.js

var router = require('express').Router();

router.get('/', async (req,res) => {
  try {
    let db = req.db,
        collection = db.get('test');

    let response = await collection.find();
    res.json(response);
  } catch(e) {
    res.status(500).json(e);
  }
});

module.exports = router;

因此,我实际上正在等待数据库连接至少在这里启动"时存在,但实际上仅是举例来说,因为我想插入一些数据以进行实际检索.这不是必需的,但基本概念是等待Promise解决:

So I am actually awaiting the database connection to at least be present on "start up" here, but really only for example since I want to insert some data to actually retrieve. It's not required, but the basic concept is to wait for the Promise to resolve:

await db.then(() => 1);

微不足道,对于您的实际代码并不是真正需要的.但是我仍然认为这是一个好习惯.

Kind of trivial, and not really required for your actual code. But I still think it's good practice.

真正的测试是通过停止mongod或以其他方式使服务器无法访问然后发出请求来完成的.

The real test is done by stopping mongod or otherwise making the server unreachable and then issuing a request.

由于我们将连接选项设置为{ bufferMaxEntries: 0 },这意味着在您尝试向数据库发出命令时立即立即,如果没有实际的连接,则将返回失败.

Since we set the connection options to { bufferMaxEntries: 0 } this means that immediately as you attempt to issue a command to the database, the failure will be returned if there is no actual connection present.

当然,当数据库再次可用时,您将不会收到错误消息,并且说明将正常进行.

Of course when the database becomes available again, you won't get the error and the instructions will happen normally.

如果没有该选项,则默认为排队"操作直到解析连接,然后实质上是播放"了缓冲区".

Without the option the default is to "en-queue" the operations until a connection is resolved and then the "buffer" is essentially "played".

您可以通过停止" mongod守护程序并发出请求来模拟此过程(就像我所做的那样).然后启动"守护程序并发出请求.它应该只返回捕获的错误响应.

You can simulate this ( as I did ) by "stopping" the mongod daemon and issuing requests. Then "starting" the daemon and issuing requests. It should simply return the caught error response.

注意:不是必需的,但实际上async/await语法的全部目的是使try..catch之类的东西再次有效,因为您实际上可以将其范围限定为块,而不是使用Promise.catch()err回调参数以捕获错误.但是,当实际上使用其中任何一种结构时,都适用相同的原理.

NOTE: Not required, but in fact the whole purpose of async/await syntax is to make things like try..catch valid again, since you can actually scope as blocks rather than using Promise.catch() or err callback arguments to trap the errors. Same principles apply when either of those structures are actually in use though.

这篇关于Mongo db与Monk的连接:如果db关闭,则错误捕获和处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆