初次提交
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { db } from '~/drizzle/db'
|
||||
import { sql } from 'drizzle-orm'
|
||||
|
||||
export default defineNitroPlugin(async (nitroApp) => {
|
||||
// 全局未处理的Promise拒绝处理器
|
||||
process.on('unhandledRejection', async (reason, promise) => {
|
||||
console.error('Unhandled Rejection at:', promise, 'reason:', reason)
|
||||
|
||||
// 检查是否是数据库连接错误
|
||||
if (reason && typeof reason === 'object' && 'message' in reason) {
|
||||
const errorMessage = (reason as Error).message
|
||||
|
||||
if (
|
||||
errorMessage.includes('ECONNRESET') ||
|
||||
errorMessage.includes('ENOTFOUND') ||
|
||||
errorMessage.includes('ETIMEDOUT') ||
|
||||
errorMessage.includes('Connection terminated') ||
|
||||
errorMessage.includes('Connection lost')
|
||||
) {
|
||||
console.log('Database connection error detected, attempting to reconnect...')
|
||||
|
||||
try {
|
||||
// 尝试重新连接数据库
|
||||
// 注意: Drizzle 没有显式的 connect/disconnect 方法
|
||||
// 连接由库自动管理
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000)) // 等待2秒
|
||||
console.log('Database reconnection successful')
|
||||
} catch (reconnectError) {
|
||||
console.error('Database reconnection failed:', reconnectError)
|
||||
|
||||
// 如果重连失败,等待更长时间后再次尝试
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
// Note: Drizzle doesn't have explicit connect/disconnect methods
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000)) // 等待5秒
|
||||
console.log('Database delayed reconnection successful')
|
||||
} catch (delayedReconnectError) {
|
||||
console.error('Database delayed reconnection failed:', delayedReconnectError)
|
||||
}
|
||||
}, 10000) // 10秒后重试
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 不要让进程退出,继续运行
|
||||
console.log('Process will continue running despite the error')
|
||||
})
|
||||
|
||||
// 全局未捕获异常处理器
|
||||
process.on('uncaughtException', (error) => {
|
||||
console.error('Uncaught Exception:', error)
|
||||
|
||||
// 检查是否是数据库相关错误
|
||||
if (
|
||||
error.message.includes('ECONNRESET') ||
|
||||
error.message.includes('ENOTFOUND') ||
|
||||
error.message.includes('ETIMEDOUT')
|
||||
) {
|
||||
console.log('Database-related uncaught exception, process will continue')
|
||||
return // 不退出进程
|
||||
}
|
||||
|
||||
// 对于其他严重错误,记录但不退出
|
||||
console.error('Non-database uncaught exception, process will continue')
|
||||
})
|
||||
|
||||
// 定期健康检查
|
||||
const healthCheckInterval = setInterval(async () => {
|
||||
try {
|
||||
await db.execute(sql`SELECT 1 as health_check`)
|
||||
} catch (error) {
|
||||
console.error('Health check failed:', error)
|
||||
|
||||
// 尝试重新连接
|
||||
try {
|
||||
// Note: Drizzle doesn't have explicit connect/disconnect methods
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
console.log('Health check reconnection successful')
|
||||
} catch (reconnectError) {
|
||||
console.error('Health check reconnection failed:', reconnectError)
|
||||
}
|
||||
}
|
||||
}, 60000) // 每分钟检查一次
|
||||
|
||||
// 在Nitro关闭时清理
|
||||
nitroApp.hooks.hook('close', () => {
|
||||
clearInterval(healthCheckInterval)
|
||||
})
|
||||
|
||||
// 数据库连接错误的特殊处理
|
||||
// 注意: Drizzle 自动管理连接
|
||||
// 我们将为数据库操作实现简单的重试机制
|
||||
const originalExecute = db.execute
|
||||
db.execute = new Proxy(originalExecute, {
|
||||
apply: async (target, thisArg, argumentsList) => {
|
||||
try {
|
||||
return await target.apply(thisArg, argumentsList)
|
||||
} catch (error) {
|
||||
if (
|
||||
error.message.includes('ECONNRESET') ||
|
||||
error.message.includes('Connection terminated')
|
||||
) {
|
||||
console.log('Query failed due to connection reset, attempting to retry...')
|
||||
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
|
||||
// 重试查询
|
||||
return await target.apply(thisArg, argumentsList)
|
||||
} catch (retryError) {
|
||||
console.error('Query retry failed:', retryError)
|
||||
throw retryError
|
||||
}
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
console.log('Global error handler initialized')
|
||||
})
|
||||
Reference in New Issue
Block a user