乐闻世界logo
搜索文章和话题

How does Mongoose manage connections and handle errors?

2月22日 20:06

Mongoose connection management and error handling are key parts of building stable applications. Properly handling connection states and errors can ensure application reliability.

Connection Management

Basic Connection

javascript
const mongoose = require('mongoose'); // Basic connection mongoose.connect('mongodb://localhost:27017/mydb'); // Connection with options mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true, maxPoolSize: 100, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000 });

Connection Event Listeners

javascript
// Connection successful mongoose.connection.on('connected', () => { console.log('Mongoose connected to MongoDB'); }); // Connection error mongoose.connection.on('error', (err) => { console.error('Mongoose connection error:', err); }); // Connection disconnected mongoose.connection.on('disconnected', () => { console.log('Mongoose disconnected'); }); // Connection closed mongoose.connection.on('close', () => { console.log('Mongoose connection closed'); });

Connection Status Check

javascript
// Check connection status console.log(mongoose.connection.readyState); // 0 = disconnected // 1 = connected // 2 = connecting // 3 = disconnecting // Helper function function isConnected() { return mongoose.connection.readyState === 1; } function isConnecting() { return mongoose.connection.readyState === 2; }

Error Handling

Connection Error Handling

javascript
// Use try-catch to handle connection errors async function connectToDatabase() { try { await mongoose.connect('mongodb://localhost:27017/mydb'); console.log('Connected to MongoDB'); } catch (error) { console.error('Failed to connect to MongoDB:', error); process.exit(1); } } // Use Promise.catch mongoose.connect('mongodb://localhost:27017/mydb') .then(() => console.log('Connected')) .catch(err => console.error('Connection error:', err));

Query Error Handling

javascript
// Query error handling async function findUser(userId) { try { const user = await User.findById(userId); if (!user) { throw new Error('User not found'); } return user; } catch (error) { if (error.name === 'CastError') { console.error('Invalid user ID format'); } else if (error.name === 'MongooseError') { console.error('Mongoose error:', error.message); } else { console.error('Unexpected error:', error); } throw error; } }

Validation Error Handling

javascript
// Validation error handling async function createUser(userData) { try { const user = await User.create(userData); return user; } catch (error) { if (error.name === 'ValidationError') { const errors = {}; Object.keys(error.errors).forEach(key => { errors[key] = error.errors[key].message; }); console.error('Validation errors:', errors); throw { message: 'Validation failed', errors }; } throw error; } }

Duplicate Key Error Handling

javascript
// Duplicate key error handling async function createUniqueUser(userData) { try { const user = await User.create(userData); return user; } catch (error) { if (error.code === 11000) { const field = Object.keys(error.keyPattern)[0]; const value = error.keyValue[field]; console.error(`Duplicate key error: ${field} = ${value}`); throw { message: `${field} already exists`, field }; } throw error; } }

Reconnection Mechanism

Auto Reconnect

javascript
// Mongoose automatically reconnects by default mongoose.connect('mongodb://localhost:27017/mydb', { // Auto reconnect configuration autoReconnect: true, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000 });

Custom Reconnection Logic

javascript
let reconnectAttempts = 0; const maxReconnectAttempts = 5; mongoose.connection.on('disconnected', () => { if (reconnectAttempts < maxReconnectAttempts) { reconnectAttempts++; console.log(`Attempting to reconnect (${reconnectAttempts}/${maxReconnectAttempts})...`); setTimeout(() => { mongoose.connect('mongodb://localhost:27017/mydb'); }, 1000 * reconnectAttempts); } else { console.error('Max reconnection attempts reached'); process.exit(1); } });

Connection Pool Management

Connection Pool Configuration

javascript
mongoose.connect('mongodb://localhost:27017/mydb', { // Connection pool configuration maxPoolSize: 100, // Maximum connections minPoolSize: 10, // Minimum connections maxIdleTimeMS: 30000, // Maximum idle time waitQueueTimeoutMS: 5000 // Wait queue timeout });

Monitor Connection Pool

javascript
// Monitor connection pool status setInterval(() => { const poolStatus = { ready: mongoose.connection.client.topology.s.pool.totalConnectionCount, active: mongoose.connection.client.topology.s.pool.activeConnectionCount, idle: mongoose.connection.client.topology.s.pool.idleConnectionCount }; console.log('Connection pool status:', poolStatus); }, 60000);

Graceful Shutdown

Graceful Shutdown Handling

javascript
async function gracefulShutdown() { console.log('Shutting down gracefully...'); try { // Close database connection await mongoose.connection.close(); console.log('MongoDB connection closed'); // Exit process process.exit(0); } catch (error) { console.error('Error during shutdown:', error); process.exit(1); } } // Listen for process exit signals process.on('SIGTERM', gracefulShutdown); process.on('SIGINT', gracefulShutdown);

Best Practices

  1. Always handle connection errors: Never ignore connection errors
  2. Use connection pools: Configure appropriate connection pool size
  3. Implement reconnection mechanism: Ensure app can recover from connection interruptions
  4. Graceful shutdown: Properly handle connection cleanup during app shutdown
  5. Monitor connection status: Regularly check connection health
  6. Categorized error handling: Take different handling strategies based on error types
  7. Logging: Record connection and error information for debugging
  8. Timeout configuration: Set reasonable timeout values to avoid long waits
标签:Mongoose