MongoError: Топология закрыта, пожалуйста, подключитесь, несмотря на установленное соединение с базой данных - PullRequest
0 голосов
/ 28 января 2020

Я пишу веб-приложение, которое использует асинхронные запросы к базе данных как часть API. В настоящее время у меня есть асин c express маршрут, который ожидает возврата функций из асин c функций. Обе эти функции возвращают логические значения и обе запрашивают базу данных. Один работает правильно, а второй - нет.

Вот настройка MongoClient:

const MongoClient = require('mongodb').MongoClient;
const uri = config.uri;                         // Contains custom url for accessing database
const client = new MongoClient(uri, { useUnifiedTopology: true}, { useNewUrlParser: true }, { connectTimeoutMS: 30000 }, { keepAlive: 1});

, где config из файла, импортированного как.

const config = require("./config.js");

и функционирует должным образом.

Вот настройка express:

app.post("/signup", async function(request, response) {
  log("POST request at /signup");

  log("BEFORE UNIQUE USER");
  const isUniqueUser = await validateUniqueUser(request.body.email, request.body.password);
  log(isUniqueUser);
  const status = {
    status: null
  };
  if (isUniqueUser) {
    log("AFTER UNIQUE USER");
    let userCreated = await createPracticeProfile(request.body.email, request.body.password);
    log("user created: " + userCreated);
    if (userCreated) {
      status.status = "user_created";
    }
    response.json(status);
  } else {
    response.json(status);
  }

  console.log("********************************end");
});

Вывод на консоль:

ПЕРЕД УНИКАЛЬНЫМ ПОЛЬЗОВАТЕЛЕМ

true (какой должно быть)

ПОСЛЕ УНИКАЛЬНОГО ПОЛЬЗОВАТЕЛЯ

MongoError: Топология закрыта.

пользователь создан: undefined

*** ... *** end

Вот функция проверки уникальности пользователя:

/*  VALIDATE_UNIQUE_USER
USE: ensure user does not have existing profile
PARAMS: email (string), password (string)
RETURN: isUniqueUser (bool)
*/
async function validateUniqueUser(email, password) {
  // connect to database
  const database = await client.connect().catch(err => {
    log("ERROR while connecting to database at: validateUniqueUser");
    console.log(err);
    client.close();
  });

  // database connection failed
  if (!database) {
    return false;
  }

  // connection successful => find user
  let user;
  try {
    user = await database.db("guitar-practice-suite").collection("users").findOne({email: email});
  } catch(err) {
    log("ERROR while finding user in database at: validateUniqueUser");
    console.log(err);
    client.close();
    return false;
  } finally {
    client.close();
    // user not found (unique)
    if (user === null || user === undefined) {
      return true;
    }
    return false;
  }
}

Функция вставки пользователя в коллекции:

/* CREATE_PRACTICE_PROFILE
USE: insert a practice profile into the database
PARAMS: email (string), password (string)
RETURN: userCreated (bool)
*/
async function createPracticeProfile(email, password) {
  // hash password
  let hashedPassword;
  try {
    hashedPassword = await new Promise((resolve, reject) => {
      bcrypt.hash(password, null, null, function(err, hash) {
        if (err) {
          reject(err);
        }
        resolve(hash)
      });
    });
  } catch(err) {
    log("ERROR while hashing password at: createPracticeProfile");
    console.log(err);
    return false;
  }

  // connect to database
  const database = await client.connect().catch(err => {
    log("ERROR while connecting to database at: validateUniqueUser");
    console.log(err);
    client.close();
  });

  // database connection failed
  if (!database) {
    return false;
  }

  // database connection successful => insert user into database
  let insertUserToUsers;
  let insertUserToExercises;
  let insertUserToCustomExercises;
  try {
    insertUserToUsers = await database.db("guitar-practice-suite").collection("users").insertOne({email: email, password: hashedPassword});
    insertUserToExercises = await database.db("guitar-practice-suite").collection("exercises").insertOne({email: email});
    insertUserToCustomExercises = await database.db("guitar-practice-suite").collection("custom-exercises").insertOne({email: email, exercises: []});
  } catch(err) {
    log("ERROR while inserting user into database at: createPracticeProfile");
    console.log(err);
    client.close();
    return false;
  } finally {
    client.close();
    return insertUserToUsers && insertUserToExercises && insertUserToCustomExercises;
  }
}

Ответы [ 3 ]

0 голосов
/ 29 января 2020

Я нашел решение проблемы, но не уверен, что понимаю причины. client.close() в блоке finally функции validateUniqueUser. Он закрывал соединение до того, как соединение в функции createPracticeProfile завершило вставку пользователя.

Когда эта строка удалена, функция работает.

0 голосов
/ 14 марта 2020

Проблема в том, что клиентская переменная должна быть заново создана,

const client = new MongoClient(uri, { useUnifiedTopology: true}, { useNewUrlParser: true }, { connectTimeoutMS: 30000 }, { keepAlive: 1});

Попробуйте поместить это в начало createPracticeProfile, validateUniqueUser и других функций

0 голосов
/ 28 января 2020

Сконфигурируйте ваше клиентское соединение, как показано ниже:

var MongoClient = require('mongodb').MongoClient;

var Server = require('mongodb').Server;

var mongoClient = new MongoClient(new Server('localhost', 27017));

mongoClient.open(function(err, mongoClient) {

  var db1 = mongoClient.db("mydb");

  mongoClient.close();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...