簡體   English   中英

Mongo db和Monk的連接:如果db關閉,則錯誤捕獲和處理

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM