[英]Mongo db with Monk: error catching and handling if db is down
我是Mongo的新手。 我需要一個簡單項目的數據庫,並最終完成了將Mongo與Monk結合使用的教程,但是我在理解如何處理錯誤方面遇到問題。
背景 :我在客戶端有一張注冊表。 當用戶單擊一個按鈕時,數據通過AJAX發送到控制器,該控制器(通過驗證,但現在不相關)將這些數據插入數據庫中,然后發送回成功或錯誤。 當數據庫啟動時,一切似乎工作正常。
問題 :如果我不啟動數據庫並嘗試發送請求,則不會返回任何錯誤。 根本沒有任何反應。 在控制台上一段時間后,我得到: POST / members / addmember--ms-- 。
我認為在這種情況下應將一些錯誤返回給用戶,那么我該怎么做呢?
職位要求如下(與本教程中的要求相當):
// 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() ”中。 那么,如何檢查該獲取是否可以完成呢? 我想,鑒於節點的異步性質,此處的try / catch之類的東西將毫無意義。 正確?
編輯:在尼爾的回答和一些嘗試之后,我整理了以下似乎可以完成工作的內容。 但是,鑒於我對此缺乏信心,如果下面的代碼行得通,因為有道理或偶然,我將不勝感激。 我添加了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})
}
});
好了,您實際上可以在連接上設置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 }
這意味着立即為你嘗試發出到數據庫命令時,發生故障時將如果沒有實際的連接存在返回。
當然,當數據庫再次可用時,您將不會收到錯誤消息,並且說明將正常進行。
如果沒有該選項,則默認值為“排隊”操作,直到解析了連接,然后實質上是“播放”了“緩沖區”。
您可以通過“停止” mongod
守護程序並發出請求來模擬此過程(就像我所做的那樣)。 然后“啟動”守護程序並發出請求。 它應該只返回捕獲的錯誤響應。
注意 :不是必需的,但實際上
async/await
語法的整個目的是使try..catch
東西再次有效,因為您實際上可以將其范圍限制為塊,而不是使用Promise.catch()
或err
回調參數來捕獲錯誤。 但是,當實際上使用其中任何一種結構時,都適用相同的原理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.