首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Monk db with Monk:如果db被关闭,捕获和处理错误

Monk db with Monk:如果db被关闭,捕获和处理错误
EN

Stack Overflow用户
提问于 2017-08-09 00:53:25
回答 1查看 2.6K关注 0票数 3

我是蒙戈的新手。对于一个简单的项目,我需要一个数据库,并在使用Mongo的教程之后结束,但是我在理解如何处理错误时遇到了问题。

背景:我在客户端有一张登记表。当用户单击一个按钮时,数据将通过AJAX发送到控制器,该控制器(验证时,但这与此无关)将此类数据插入数据库并发送回成功或错误。当数据库启动时,一切似乎都正常。

问题:如果我不启动db并尝试发送请求,则不会返回错误。只是什么都没发生。在控制台上呆了一段时间后,我得到了: POST /members/addmember - ms --。

在这种情况下,我认为应该将一些错误返回给用户,那么如何才能这样做呢?

post请求如下(与教程中的大致相同):

代码语言:javascript
复制
// 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出现问题,那么问题实际上甚至早于插入,即"db.get()“中的问题。那么,如何检查是否真的可以这样做呢?我认为,考虑到节点的异步性质,在这里尝试/捕捉之类的东西是没有意义的。对,是这样?

编辑:经过尼尔的回答和一点尝试,我整理了以下似乎完成这项工作的内容。然而,考虑到我对此缺乏的信心,如果下面的代码是有意义的或者是偶然的,我希望能给你一个评论。我添加了bufferMaxEntries: 0选项,并对控制器进行了如下修改。在ajax回调中,我现在有一个警报,显示抛出的错误消息(如果有的话)。

代码语言:javascript
复制
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})
    }

});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-09 03:23:05

实际上,您可以在连接上设置bufferMaxEntries选项(在Db下面记录,但对于对象的使用不推荐使用,而是在“展示的顶层”使用),这实际上是在没有连接的情况下在驱动程序上停止“队列”请求。

最起码的例子是:

index.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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解决:

代码语言:javascript
复制
await db.then(() => 1);

有点琐碎,并不是您实际代码所需要的。但我还是觉得这是个好练习。

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

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

当然,当数据库再次可用时,您将不会得到错误,并且指令将正常发生。

如果没有这个选项,默认的做法是“n-队列”操作,直到连接被解析,然后“缓冲区”基本上被“播放”。

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

注意到:不需要,但实际上,async/await语法的全部目的是使类似try..catch的内容再次有效,因为您实际上可以作为块进行作用,而不是使用Promise.catch()err回调参数来捕获错误。然而,当这两种结构中的任何一种实际使用时,都适用同样的原则。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45580025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档