我是蒙戈的新手。对于一个简单的项目,我需要一个数据库,并在使用Mongo的教程之后结束,但是我在理解如何处理错误时遇到了问题。
背景:我在客户端有一张登记表。当用户单击一个按钮时,数据将通过AJAX发送到控制器,该控制器(验证时,但这与此无关)将此类数据插入数据库并发送回成功或错误。当数据库启动时,一切似乎都正常。
问题:如果我不启动db并尝试发送请求,则不会返回错误。只是什么都没发生。在控制台上呆了一段时间后,我得到了: POST /members/addmember - ms --。
在这种情况下,我认为应该将一些错误返回给用户,那么如何才能这样做呢?
post请求如下(与教程中的大致相同):
// 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回调中,我现在有一个警报,显示抛出的错误消息(如果有的话)。
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})
}
});发布于 2017-08-09 03:23:05
实际上,您可以在连接上设置bufferMaxEntries选项(在Db下面记录,但对于对象的使用不推荐使用,而是在“展示的顶层”使用),这实际上是在没有连接的情况下在驱动程序上停止“队列”请求。
最起码的例子是:
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解决:
await db.then(() => 1);有点琐碎,并不是您实际代码所需要的。但我还是觉得这是个好练习。
真正的测试是通过停止mongod或以其他方式使服务器无法访问,然后发出请求来完成的。
由于我们将连接选项设置为{ bufferMaxEntries: 0 } --这意味着当您尝试向数据库发出命令时,立即向发送命令,如果没有实际连接,则将返回失败。
当然,当数据库再次可用时,您将不会得到错误,并且指令将正常发生。
如果没有这个选项,默认的做法是“n-队列”操作,直到连接被解析,然后“缓冲区”基本上被“播放”。
您可以通过“停止”mongod守护进程并发出请求来模拟这个过程(就像我所做的那样)。然后“启动”守护进程并发出请求。它应该只返回捕获的错误响应。
注意到:不需要,但实际上,
async/await语法的全部目的是使类似try..catch的内容再次有效,因为您实际上可以作为块进行作用,而不是使用Promise.catch()或err回调参数来捕获错误。然而,当这两种结构中的任何一种实际使用时,都适用同样的原则。
https://stackoverflow.com/questions/45580025
复制相似问题