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

Mongoose 如何管理连接和处理错误?

2月22日 20:06

Mongoose 连接管理和错误处理是构建稳定应用的关键部分。正确处理连接状态和错误可以确保应用的可靠性。

连接管理

基本连接

javascript
const mongoose = require('mongoose'); // 基本连接 mongoose.connect('mongodb://localhost:27017/mydb'); // 带选项的连接 mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true, maxPoolSize: 100, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000 });

连接事件监听

javascript
// 连接成功 mongoose.connection.on('connected', () => { console.log('Mongoose connected to MongoDB'); }); // 连接错误 mongoose.connection.on('error', (err) => { console.error('Mongoose connection error:', err); }); // 连接断开 mongoose.connection.on('disconnected', () => { console.log('Mongoose disconnected'); }); // 连接关闭 mongoose.connection.on('close', () => { console.log('Mongoose connection closed'); });

连接状态检查

javascript
// 检查连接状态 console.log(mongoose.connection.readyState); // 0 = disconnected // 1 = connected // 2 = connecting // 3 = disconnecting // 辅助函数 function isConnected() { return mongoose.connection.readyState === 1; } function isConnecting() { return mongoose.connection.readyState === 2; }

错误处理

连接错误处理

javascript
// 使用 try-catch 处理连接错误 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); } } // 使用 Promise.catch mongoose.connect('mongodb://localhost:27017/mydb') .then(() => console.log('Connected')) .catch(err => console.error('Connection error:', err));

查询错误处理

javascript
// 查询错误处理 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; } }

验证错误处理

javascript
// 验证错误处理 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; } }

重复键错误处理

javascript
// 重复键错误处理 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; } }

重连机制

自动重连

javascript
// Mongoose 默认会自动重连 mongoose.connect('mongodb://localhost:27017/mydb', { // 自动重连配置 autoReconnect: true, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000 });

自定义重连逻辑

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); } });

连接池管理

连接池配置

javascript
mongoose.connect('mongodb://localhost:27017/mydb', { // 连接池配置 maxPoolSize: 100, // 最大连接数 minPoolSize: 10, // 最小连接数 maxIdleTimeMS: 30000, // 最大空闲时间 waitQueueTimeoutMS: 5000 // 等待队列超时 });

监控连接池

javascript
// 监控连接池状态 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);

优雅关闭

优雅关闭处理

javascript
async function gracefulShutdown() { console.log('Shutting down gracefully...'); try { // 关闭数据库连接 await mongoose.connection.close(); console.log('MongoDB connection closed'); // 退出进程 process.exit(0); } catch (error) { console.error('Error during shutdown:', error); process.exit(1); } } // 监听进程退出信号 process.on('SIGTERM', gracefulShutdown); process.on('SIGINT', gracefulShutdown);

最佳实践

  1. 始终处理连接错误:不要忽略连接错误
  2. 使用连接池:配置合适的连接池大小
  3. 实现重连机制:确保应用能从连接中断中恢复
  4. 优雅关闭:正确处理应用关闭时的连接清理
  5. 监控连接状态:定期检查连接健康状态
  6. 错误分类处理:根据错误类型采取不同的处理策略
  7. 日志记录:记录连接和错误信息以便调试
  8. 超时配置:设置合理的超时时间避免长时间等待
标签:Mongoose