Manejar errores de MongoDB

MongoDBMongoDBBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderá a manejar varios errores de MongoDB, incluyendo errores de conexión, errores de escritura, errores de consulta y problemas de claves duplicadas. Explorará diferentes tipos de errores de conexión, como cadenas de conexión incorrectas y problemas de autenticación, y aprenderá a diagnosticarlos y resolverlos. Además, descubrirá técnicas para manejar errores de escritura, manejar errores de consulta y reintentar operaciones fallidas para garantizar la confiabilidad y robustez de sus aplicaciones de MongoDB.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/IndexingGroup(["Indexing"]) mongodb(("MongoDB")) -.-> mongodb/ErrorHandlingGroup(["Error Handling"]) mongodb/BasicOperationsGroup -.-> mongodb/start_mongodb_shell("Start MongoDB Shell") mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/BasicOperationsGroup -.-> mongodb/update_document("Update Document") mongodb/BasicOperationsGroup -.-> mongodb/bulk_update_documents("Bulk Update Documents") mongodb/QueryOperationsGroup -.-> mongodb/find_documents("Find Documents") mongodb/IndexingGroup -.-> mongodb/create_index("Create Index") mongodb/ErrorHandlingGroup -.-> mongodb/handle_connection_errors("Handle Connection Errors") mongodb/ErrorHandlingGroup -.-> mongodb/handle_write_errors("Handle Write Errors") subgraph Lab Skills mongodb/start_mongodb_shell -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/insert_document -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/update_document -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/bulk_update_documents -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/find_documents -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/create_index -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/handle_connection_errors -.-> lab-422085{{"Manejar errores de MongoDB"}} mongodb/handle_write_errors -.-> lab-422085{{"Manejar errores de MongoDB"}} end

Manejar errores de conexión

En este paso, aprenderá a manejar los errores de conexión en MongoDB, que son retos comunes al trabajar con bases de datos. Los errores de conexión pueden ocurrir por varios motivos, como cadenas de conexión incorrectas, problemas de red o problemas de autenticación.

Comprender los errores de conexión de MongoDB

Comencemos explorando diferentes tipos de errores de conexión y cómo diagnosticarlos y resolverlos. Usaremos la shell de MongoDB (mongosh) para demostrar estos escenarios.

Primero, abra una terminal y inicie la shell de MongoDB:

mongosh

Simulando errores de conexión

1. Cadena de conexión incorrecta

Intente conectarse a una instancia de MongoDB que no existe:

mongosh "mongodb://localhost:27018/testdb"

Salida de ejemplo:

MongoNetworkError: failed to connect to server [localhost:27018] on first connect

Este error ocurre cuando la cadena de conexión apunta a un puerto o host en el que no está ejecutando un servidor de MongoDB.

2. Errores de autenticación

Vamos a simular un error de autenticación usando un nombre de usuario o contraseña incorrectos:

mongosh "mongodb://wronguser:wrongpassword@localhost:27017/testdb"

Salida de ejemplo:

MongoAuthenticationError: Authentication failed

Manejar errores de conexión en la práctica

Para manejar efectivamente los errores de conexión, debe:

  1. Verificar los detalles de la conexión
  2. Comprobar la conectividad de red
  3. Asegurarse de que el servicio de MongoDB esté en ejecución
  4. Validar las credenciales de autenticación
Ejemplo de manejo de errores de conexión

Cree un script simple de manejo de errores en Node.js para demostrar una gestión de conexión robusta:

const { MongoClient } = require("mongodb");

const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri, {
  serverSelectionTimeoutMS: 5000,
  connectTimeoutMS: 5000
});

async function connectToMongoDB() {
  try {
    await client.connect();
    console.log("Successfully connected to MongoDB");
  } catch (error) {
    console.error("Connection error:", error.message);
    // Implement retry logic or fallback mechanism
  } finally {
    await client.close();
  }
}

connectToMongoDB();

Este script demuestra:

  • Establecer los tiempos de espera de conexión
  • Capturar los errores de conexión
  • Registrar los detalles del error
  • Cerrar correctamente la conexión

Mejores prácticas para el manejo de errores de conexión

  1. Siempre use los tiempos de espera de conexión
  2. Implemente mecanismos de reintentos
  3. Registre información detallada de errores
  4. Valide las cadenas de conexión antes de conectarse
  5. Use variables de entorno para los detalles de la conexión

Manejar errores de escritura

En este paso, aprenderá a manejar los errores de escritura en MongoDB, que pueden ocurrir durante las operaciones de inserción, actualización o eliminación de documentos. Comprender y manejar estos errores es crucial para mantener la integridad de los datos y prevenir problemas inesperados en su base de datos.

Comprender los errores de escritura en MongoDB

Exploremos diferentes tipos de errores de escritura y cómo manejarlos efectivamente usando la shell de MongoDB (mongosh).

Primero, asegúrese de estar conectado a la shell de MongoDB:

mongosh

Tipos de errores de escritura

1. Error de clave duplicada

Cree una colección con un índice único para demostrar los errores de clave duplicada:

use errorlab
db.users.createIndex({ email: 1 }, { unique: true })
db.users.insertMany([
  { name: "John Doe", email: "[email protected]" },
  { name: "Jane Doe", email: "[email protected]" }
])

Salida de ejemplo:

MongoError: E11000 duplicate key error collection: errorlab.users index: email_1 dup key: { email: "[email protected]" }
2. Error de validación

Cree una validación de esquema para evitar la inserción de datos no válidos:

db.createCollection("products", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: ["name", "price"],
         properties: {
            name: {
               bsonType: "string",
               description: "must be a string and is required"
            },
            price: {
               bsonType: "number",
               minimum: 0,
               description: "must be a positive number and is required"
            }
         }
      }
   }
})

// Try inserting an invalid document
db.products.insertOne({ name: 123, price: -10 })

Salida de ejemplo:

MongoError: Document failed validation

Manejar errores de escritura en la práctica

Manejo de errores con Node.js

Cree un script robusto de manejo de errores de escritura:

const { MongoClient } = require("mongodb");

async function handleWriteErrors() {
  const uri = "mongodb://localhost:27017";
  const client = new MongoClient(uri);

  try {
    await client.connect();
    const database = client.db("errorlab");
    const users = database.collection("users");

    try {
      await users.insertOne({
        name: "Alice",
        email: "[email protected]"
      });
      console.log("Document inserted successfully");
    } catch (writeError) {
      if (writeError.code === 11000) {
        console.error("Duplicate key error:", writeError.message);
        // Implement custom handling for duplicate keys
      } else {
        console.error("Write error:", writeError);
      }
    }
  } catch (connectionError) {
    console.error("Connection error:", connectionError);
  } finally {
    await client.close();
  }
}

handleWriteErrors();

Mejores prácticas para el manejo de errores de escritura

  1. Use índices únicos para evitar entradas duplicadas
  2. Implemente la validación de esquema
  3. Use bloques try-catch para el manejo de errores
  4. Registre información detallada de errores
  5. Implemente mecanismos de reintentos o de recuperación alternativa

Manejar errores de consulta

En este paso, aprenderá a manejar varios errores de consulta en MongoDB, comprendiendo los peligros comunes y implementando estrategias sólidas de manejo de errores para las consultas de base de datos.

Comprender los errores de consulta en MongoDB

Exploremos diferentes tipos de errores de consulta y cómo manejarlos efectivamente usando la shell de MongoDB (mongosh).

Primero, asegúrese de estar conectado a la shell de MongoDB:

mongosh

Preparando datos de muestra

Cree una colección de muestra para nuestras demostraciones de errores de consulta:

use querylab
db.products.insertMany([
  { name: "Laptop", price: 1000, category: "Electronics" },
  { name: "Smartphone", price: 500, category: "Electronics" },
  { name: "Headphones", price: 200, category: "Accessories" }
])

Tipos de errores de consulta

1. Sintaxis de consulta no válida

Demuestre un error común de sintaxis de consulta:

// Incorrect comparison operator
db.products.find({ price: { $invalidOperator: 500 } })

Salida de ejemplo:

MongoError: unknown top level operator: $invalidOperator
2. Consulta en un campo no existente

Intente consultar un campo que no existe:

// Query on a field that doesn't exist
db.products.find({ nonexistentField: "value" })

Esto no generará un error, pero devolverá un conjunto de resultados vacío.

3. Desajuste de tipos en consultas

Demuestre los desafíos de consulta relacionados con los tipos:

// Type mismatch query
db.products.find({ price: "500" })  // String instead of number

Manejo avanzado de errores de consulta

Cree un script de Node.js para demostrar un manejo robusto de errores de consulta:

const { MongoClient } = require("mongodb");

async function handleQueryErrors() {
  const uri = "mongodb://localhost:27017";
  const client = new MongoClient(uri);

  try {
    await client.connect();
    const database = client.db("querylab");
    const products = database.collection("products");

    try {
      // Safe query with error handling
      const query = { price: { $gt: 0 } };
      const options = {
        projection: { _id: 0, name: 1, price: 1 },
        limit: 10
      };

      const cursor = products.find(query, options);
      const results = await cursor.toArray();

      if (results.length === 0) {
        console.log("No matching documents found");
      } else {
        console.log("Query results:", results);
      }
    } catch (queryError) {
      // Specific error handling
      if (queryError.name === "MongoError") {
        console.error("MongoDB Query Error:", queryError.message);
      } else {
        console.error("Unexpected error:", queryError);
      }
    }
  } catch (connectionError) {
    console.error("Connection error:", connectionError);
  } finally {
    await client.close();
  }
}

handleQueryErrors();

Mejores prácticas para el manejo de errores de consulta

  1. Siempre valide la entrada antes de realizar una consulta
  2. Use bloques try-catch para el manejo de errores
  3. Implemente la comprobación de tipos
  4. Use la proyección para controlar los campos devueltos
  5. Agregue un registro de errores adecuado
  6. Maneje los conjuntos de resultados vacíos de manera adecuada

Corregir claves duplicadas

En este paso, aprenderá a identificar, prevenir y resolver errores de clave duplicada en MongoDB, un desafío común al mantener la integridad de los datos.

Comprender los desafíos de claves duplicadas

Exploremos estrategias para manejar claves duplicadas usando la shell de MongoDB (mongosh).

Primero, asegúrese de estar conectado a la shell de MongoDB:

mongosh

Creando un índice único

Comience creando una colección con una restricción única:

use duplicatelab
db.users.createIndex({ email: 1 }, { unique: true })

Manejando escenarios de claves duplicadas

1. Evitando inserciones duplicadas

Intente insertar documentos duplicados:

db.users.insertMany([
  { name: "John Doe", email: "[email protected]" },
  { name: "Jane Doe", email: "[email protected]" }
])

Salida de ejemplo:

MongoError: E11000 duplicate key error collection: duplicatelab.users index: email_1 dup key: { email: "[email protected]" }
2. Manejando duplicados con upsert

Use el método updateOne con upsert para manejar duplicados:

db.users.updateOne(
  { email: "[email protected]" },
  { $set: {
    name: "John Doe Updated",
    lastUpdated: new Date()
  }},
  { upsert: true }
)

Manejo avanzado de claves duplicadas

Cree un script de Node.js para demostrar un manejo robusto de claves duplicadas:

const { MongoClient } = require("mongodb");

async function handleDuplicateKeys() {
  const uri = "mongodb://localhost:27017";
  const client = new MongoClient(uri);

  try {
    await client.connect();
    const database = client.db("duplicatelab");
    const users = database.collection("users");

    // Asegurarse de tener un índice único
    await users.createIndex({ email: 1 }, { unique: true });

    const userDocuments = [
      { name: "Alice", email: "[email protected]" },
      { name: "Bob", email: "[email protected]" }
    ];

    try {
      // Escribir en lote con manejo de duplicados
      const bulkOperations = userDocuments.map((user) => ({
        updateOne: {
          filter: { email: user.email },
          update: { $set: user },
          upsert: true
        }
      }));

      const result = await users.bulkWrite(bulkOperations);
      console.log("Resultado de escritura en lote:", result);
    } catch (writeError) {
      if (writeError.code === 11000) {
        console.error("Error de clave duplicada:", writeError.message);
        // Implementar lógica personalizada de manejo de duplicados
      } else {
        console.error("Error inesperado de escritura:", writeError);
      }
    }
  } catch (connectionError) {
    console.error("Error de conexión:", connectionError);
  } finally {
    await client.close();
  }
}

handleDuplicateKeys();

Mejores prácticas para el manejo de claves duplicadas

  1. Use índices únicos para evitar duplicados
  2. Implemente estrategias de upsert
  3. Use operaciones de escritura en lote con cuidado
  4. Registre y siga las entradas duplicadas
  5. Considere identificadores únicos alternativos
  6. Implemente lógica de deduplicación a nivel de aplicación

Reintentar operaciones fallidas

En este paso, aprenderá a implementar sólidos mecanismos de reintentos para las operaciones fallidas de MongoDB, lo que garantiza que su aplicación pueda manejar errores transitorios y problemas de red.

Comprender las estrategias de reintento de operaciones

Exploremos diferentes enfoques para reintentar operaciones de base de datos fallidas usando la shell de MongoDB (mongosh) y Node.js.

Primero, asegúrese de estar conectado a la shell de MongoDB:

mongosh

Preparando el entorno de prueba

Cree una colección de muestra para demostrar los mecanismos de reintento:

use retrylab
db.transactions.insertMany([
  { id: 1, amount: 100, status: "pending" },
  { id: 2, amount: 200, status: "pending" }
])

Estrategias de reintento

1. Mecanismo básico de reintento

Cree un script de Node.js con una lógica de reintento simple:

const { MongoClient } = require("mongodb");

async function retryOperation(operation, maxRetries = 3) {
  let retries = 0;

  while (retries < maxRetries) {
    try {
      return await operation();
    } catch (error) {
      retries++;
      console.log(`Intento ${retries} fallido:`, error.message);

      // Retraso exponencial
      const delay = Math.pow(2, retries) * 1000;
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }

  throw new Error("Se excedió el número máximo de reintentos");
}

async function performMongoOperation() {
  const uri = "mongodb://localhost:27017";
  const client = new MongoClient(uri);

  try {
    await client.connect();
    const database = client.db("retrylab");
    const transactions = database.collection("transactions");

    // Simular una operación que podría fallar
    await retryOperation(async () => {
      const result = await transactions.updateOne(
        { id: 1 },
        { $set: { status: "completed" } }
      );

      if (result.modifiedCount === 0) {
        throw new Error("La actualización falló");
      }

      console.log("La transacción se actualizó correctamente");
    });
  } catch (error) {
    console.error("La operación final falló:", error.message);
  } finally {
    await client.close();
  }
}

performMongoOperation();
2. Reintento avanzado con manejo de errores específicos

Mejore el mecanismo de reintento para manejar tipos específicos de errores:

async function advancedRetryOperation(operation, maxRetries = 3) {
  const retryableErrors = [
    "MongoNetworkError",
    "MongoTimeoutError",
    "MongoServerSelectionError"
  ];

  let retries = 0;

  while (retries < maxRetries) {
    try {
      return await operation();
    } catch (error) {
      // Verificar si el error es reintentable
      if (!retryableErrors.includes(error.name)) {
        throw error;
      }

      retries++;
      console.log(`Error reintentable (${error.name}). Intento ${retries}`);

      // Implementar un retraso exponencial con jitter
      const delay = Math.min(
        30000,
        Math.pow(2, retries) * 1000 * (1 + Math.random())
      );

      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }

  throw new Error(
    "Se excedió el número máximo de reintentos para errores reintentables"
  );
}

Mejores prácticas para los reintentos de operaciones

  1. Implementar un retraso exponencial
  2. Usar retrasos con jitter para evitar el problema del "bóvil de truenos"
  3. Limitar el número máximo de reintentos
  4. Manejar solo errores específicos y reintentables
  5. Registrar los intentos de reintento y los resultados finales
  6. Considerar la consistencia transaccional

Resumen

En este laboratorio, aprendió a manejar varios tipos de errores de conexión de MongoDB, incluyendo cadenas de conexión incorrectas, problemas de autenticación y problemas de red. Exploró diferentes escenarios de error usando la shell de MongoDB y aprendió las mejores prácticas para diagnosticar y resolver errores de conexión, como verificar los detalles de conexión, comprobar la conectividad de red, asegurarse de que el servicio de MongoDB esté en ejecución y validar las credenciales de autenticación. También implementó un script simple de manejo de errores en Node.js para demostrar un manejo robusto de la conexión, que incluye establecer tiempos de espera adecuados y manejar los errores de manera adecuada.