0

10 回中 8 回、すべてがうまく接続されています。そうは言っても、時々MongoClient must be connected before calling MongoClient.prototype.dbエラーが発生します。確実に (100%) 動作するようにコードを変更するにはどうすればよいですか?

Now Zeit プラットフォームの作成者の 1 人からのコード スニペットを試してみました。

私のハンドラー

const { send } = require('micro');
const { handleErrors } = require('../../../lib/errors');
const cors = require('../../../lib/cors')();
const qs = require('micro-query');
const mongo = require('../../../lib/mongo');
const { ObjectId } = require('mongodb');

const handler = async (req, res) => {
  let { limit = 5 } = qs(req);

  limit = parseInt(limit);
  limit = limit > 10 ? 10 : limit;

  const db = await mongo();

  const games = await db
    .collection('games_v3')
    .aggregate([
      {
        $match: {
          removed: { $ne: true }
        }
      },
      { $sample: { size: limit } }
    ])
    .toArray();

  send(res, 200, games);
};

module.exports = handleErrors(cors(handler));

ラムダがまだ暖かい場合に接続を再利用する私のmongoスクリプト:

// Based on: https://spectrum.chat/zeit/now/now-2-0-connect-to-database-on-every-function-invocation~e25b9e64-6271-4e15-822a-ddde047fa43d?m=MTU0NDkxODA3NDExMg==
const MongoClient = require('mongodb').MongoClient;

if (!process.env.MONGODB_URI) {
  throw new Error('Missing env MONGODB_URI');
}

let client = null;

module.exports = function getDb(fn) {
  if (client && !client.isConnected) {
    client = null;
    console.log('[mongo] client discard');
  }

  if (client === null) {
    client = new MongoClient(process.env.MONGODB_URI, {
      useNewUrlParser: true
    });
    console.log('[mongo] client init');
  } else if (client.isConnected) {
    console.log('[mongo] client connected, quick return');
    return client.db(process.env.MONGO_DB_NAME);
  }

  return new Promise((resolve, reject) => {
    client.connect(err => {
      if (err) {
        client = null;
        console.error('[mongo] client err', err);
        return reject(err);
      }

      console.log('[mongo] connected');
      resolve(client.db(process.env.MONGO_DB_NAME));
    });
  });
};

ハンドラーを 100% 信頼できるものにする必要があります。

4

3 に答える 3

0

同じ問題がありました。私の場合、前の getDb() 呼び出しが返される前に getDb() を呼び出すことが原因でした。この場合、「client.isConnected」は接続中にもかかわらず true を返すと思います。

これは、ある場所で getDb() 呼び出しの前に「await」を置くのを忘れたことが原因でした。以下を使用して getDb からコールスタックを出力することで、どれを追跡しましたか。

console.log(new Error().stack);

質問のサンプル コードでは同じ問題は見られませんが、表示されていない別のコードによってトリガーされる可能性があります。

于 2019-02-22T16:29:55.600 に答える