Что делать, если при записи данных в NoSQL-базу (например, MongoDB) произошла ошибка?

«Что делать, если при записи данных в NoSQL-базу (например, MongoDB) произошла ошибка?» — вопрос из категории Базы данных, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Node.js приложении с MongoDB я реализую многоуровневую стратегию обработки ошибок.

1. Повторные попытки (Retry Logic): Для сетевых сбоев или временных ошибок сервера использую библиотеку retry или экспоненциальную задержку.

const { MongoNetworkError } = require('mongodb');

async function insertWithRetry(document, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const result = await db.collection('users').insertOne(document);
      return result;
    } catch (err) {
      if (err instanceof MongoNetworkError && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // Экспоненциальная задержка
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw err; // Если ошибка не временная или попытки кончились
    }
  }
}

2. Валидация на уровне приложения: Перед записью проверяю данные с помощью Joi или Zod, чтобы отсечь заведомо невалидные запросы.

3. Использование сессий и транзакций (для репликасетов): Для согласованности нескольких операций.

const session = client.startSession();
try {
  session.startTransaction();
  await collection1.insertOne(doc1, { session });
  await collection2.updateOne(filter, update, { session });
  await session.commitTransaction();
} catch (err) {
  await session.abortTransaction();
  throw err;
} finally {
  session.endSession();
}

4. Логирование и мониторинг: Все ошибки логирую с полным контекстом (запрос, пользователь, стек) в Sentry или аналогичную систему. Для критически важных данных, которые не удалось сохранить, реализую Dead Letter Queue — запись в Redis или отдельную коллекцию MongoDB для последующего разбора и повторной обработки.