zhin-error-handling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseZhin Error Handling Guide
Zhin错误处理指南
Use this skill to handle errors in Zhin plugins using the built-in error classes and resilience patterns.
本技能介绍如何使用内置错误类和弹性模式处理Zhin插件中的错误。
Error Class Hierarchy
错误类层级
All custom errors extend :
ZhinErrorZhinError (base)
├── ConfigError — Configuration issues
├── PluginError — Plugin loading/execution failures
├── AdapterError — Adapter/bot connection issues
├── ConnectionError — Network/connection failures (retryable flag)
├── MessageError — Message processing errors
├── ContextError — Context injection failures
├── ValidationError — Input validation errors
├── PermissionError — Permission/authorization errors
└── TimeoutError — Operation timeout errors所有自定义错误均继承自:
ZhinErrorZhinError (基类)
├── ConfigError — 配置问题
├── PluginError — 插件加载/执行失败
├── AdapterError — 适配器/机器人连接问题
├── ConnectionError — 网络/连接失败(带有可重试标记)
├── MessageError — 消息处理错误
├── ContextError — 上下文注入失败
├── ValidationError — 输入验证错误
├── PermissionError — 权限/授权错误
└── TimeoutError — 操作超时错误Using Error Classes
使用错误类
ts
import {
ZhinError, ConfigError, PluginError, AdapterError,
ConnectionError, MessageError, ContextError,
ValidationError, PermissionError, TimeoutError,
} from '@zhin.js/core'
// Configuration error
throw new ConfigError('Missing API key', { field: 'apiKey' })
// Plugin error with plugin name
throw new PluginError('Failed to initialize', 'my-plugin', { reason: 'missing dep' })
// Adapter error with adapter and bot name
throw new AdapterError('Connection refused', 'discord', 'bot-1')
// Connection error (retryable)
throw new ConnectionError('Server unreachable', true)
// Permission error
throw new PermissionError('Admin required', 'user-123', 'bot_admin')
// Timeout error
throw new TimeoutError('Operation timed out', 30000)ts
import {
ZhinError, ConfigError, PluginError, AdapterError,
ConnectionError, MessageError, ContextError,
ValidationError, PermissionError, TimeoutError,
} from '@zhin.js/core'
// 配置错误
throw new ConfigError('缺少API密钥', { field: 'apiKey' })
// 带插件名称的插件错误
throw new PluginError('初始化失败', 'my-plugin', { reason: '缺少依赖' })
// 带适配器和机器人名称的适配器错误
throw new AdapterError('连接被拒绝', 'discord', 'bot-1')
// 可重试的连接错误
throw new ConnectionError('服务器不可达', true)
// 权限错误
throw new PermissionError('需要管理员权限', 'user-123', 'bot_admin')
// 超时错误
throw new TimeoutError('操作超时', 30000)Error Serialization
错误序列化
ts
try {
// ...
} catch (err) {
if (err instanceof ZhinError) {
console.log(err.toJSON()) // Full JSON representation
console.log(err.toUserString()) // User-friendly: "[CODE] message"
console.log(err.code) // Error code string
console.log(err.timestamp) // When the error occurred
console.log(err.context) // Additional context data
}
}ts
try {
// ...
} catch (err) {
if (err instanceof ZhinError) {
console.log(err.toJSON()) // 完整JSON表示
console.log(err.toUserString()) // 用户友好格式:"[错误码] 消息"
console.log(err.code) // 错误码字符串
console.log(err.timestamp) // 错误发生时间
console.log(err.context) // 附加上下文数据
}
}ErrorManager
ErrorManager
Central error handler registry for organized error handling:
ts
import { errorManager, ErrorHandler } from '@zhin.js/core'
// Register handler for specific error types
errorManager.register('ConnectionError', async (error, context) => {
console.log('Connection issue:', error.message)
// Notify admin, log to database, etc.
})
// Register global handler (called for all errors)
errorManager.registerGlobal(async (error, context) => {
console.log('Error occurred:', error.message)
})
// Handle an error
try {
await riskyOperation()
} catch (error) {
await errorManager.handle(error as Error, { source: 'my-plugin' })
}
// Clean up handlers
errorManager.unregister('ConnectionError', myHandler)
errorManager.clear()集中式错误处理注册中心,用于规范化错误处理:
ts
import { errorManager, ErrorHandler } from '@zhin.js/core'
// 为特定错误类型注册处理程序
errorManager.register('ConnectionError', async (error, context) => {
console.log('连接问题:', error.message)
// 通知管理员、记录到数据库等
})
// 注册全局处理程序(处理所有错误)
errorManager.registerGlobal(async (error, context) => {
console.log('发生错误:', error.message)
})
// 处理错误
try {
await riskyOperation()
} catch (error) {
await errorManager.handle(error as Error, { source: 'my-plugin' })
}
// 清理处理程序
errorManager.unregister('ConnectionError', myHandler)
errorManager.clear()RetryManager
RetryManager
Automatic retry with exponential backoff:
ts
import { RetryManager } from '@zhin.js/core'
const result = await RetryManager.retry(
async () => {
// Operation that might fail
return await fetchExternalAPI()
},
{
maxRetries: 3, // Maximum retry attempts
delay: 1000, // Base delay in ms
exponentialBackoff: true, // Double delay each retry
retryCondition: (error) => {
// Only retry ConnectionErrors
return error instanceof ConnectionError && error.retryable
},
}
)支持指数退避的自动重试机制:
ts
import { RetryManager } from '@zhin.js/core'
const result = await RetryManager.retry(
async () => {
// 可能失败的操作
return await fetchExternalAPI()
},
{
maxRetries: 3, // 最大重试次数
delay: 1000, // 基础延迟(毫秒)
exponentialBackoff: true, // 每次重试延迟翻倍
retryCondition: (error) => {
// 仅对ConnectionError进行重试
return error instanceof ConnectionError && error.retryable
},
}
)Retry Timing
重试时序
With and :
exponentialBackoff: truedelay: 1000- Attempt 1 → immediate
- Attempt 2 → wait 1000ms
- Attempt 3 → wait 2000ms
- Attempt 4 → wait 4000ms
当且时:
exponentialBackoff: truedelay: 1000- 第1次尝试 → 立即执行
- 第2次尝试 → 等待1000毫秒
- 第3次尝试 → 等待2000毫秒
- 第4次尝试 → 等待4000毫秒
CircuitBreaker
CircuitBreaker
Prevent cascading failures with the circuit breaker pattern:
ts
import { CircuitBreaker } from '@zhin.js/core'
const breaker = new CircuitBreaker(
5, // failureThreshold — open after 5 failures
60000, // timeoutMs — stay open for 60s
10000 // monitoringPeriodMs
)
try {
const result = await breaker.execute(async () => {
return await callExternalService()
})
} catch (error) {
if (error.message === 'Circuit breaker is OPEN') {
// Service is down, use fallback
return fallbackValue
}
throw error
}
// Check state
console.log(breaker.getState()) // 'CLOSED' | 'OPEN' | 'HALF_OPEN'
// Manual reset
breaker.reset()通过断路器模式防止级联故障:
ts
import { CircuitBreaker } from '@zhin.js/core'
const breaker = new CircuitBreaker(
5, // failureThreshold — 失败5次后打开断路器
60000, // timeoutMs — 保持打开状态60秒
10000 // monitoringPeriodMs
)
try {
const result = await breaker.execute(async () => {
return await callExternalService()
})
} catch (error) {
if (error.message === 'Circuit breaker is OPEN') {
// 服务已下线,使用回退值
return fallbackValue
}
throw error
}
// 检查状态
console.log(breaker.getState()) // 'CLOSED' | 'OPEN' | 'HALF_OPEN'
// 手动重置
breaker.reset()Circuit Breaker States
断路器状态
| State | Description |
|---|---|
| Normal operation, requests pass through |
| Too many failures, requests are rejected immediately |
| Timeout expired, one test request is allowed |
| 状态 | 描述 |
|---|---|
| 正常运行状态,请求可正常通过 |
| 失败次数过多,请求被直接拒绝 |
| 超时时间已过,允许发送一次测试请求 |
Pattern: Plugin Error Handling
模式:插件错误处理
ts
import { usePlugin, PluginError, RetryManager } from 'zhin.js'
const plugin = usePlugin()
plugin.onMounted(async () => {
try {
const data = await RetryManager.retry(
() => loadExternalResource(),
{ maxRetries: 3, delay: 2000 }
)
plugin.logger.info('Resource loaded successfully')
} catch (error) {
plugin.logger.error(`Failed to load resource: ${error.message}`)
throw new PluginError('Initialization failed', plugin.name, {
originalError: error.message,
})
}
})ts
import { usePlugin, PluginError, RetryManager } from 'zhin.js'
const plugin = usePlugin()
plugin.onMounted(async () => {
try {
const data = await RetryManager.retry(
() => loadExternalResource(),
{ maxRetries: 3, delay: 2000 }
)
plugin.logger.info('资源加载成功')
} catch (error) {
plugin.logger.error(`资源加载失败: ${error.message}`)
throw new PluginError('初始化失败', plugin.name, {
originalError: error.message,
})
}
})Checklist
检查清单
- Use specific error classes instead of generic .
Error - Include context information when creating errors.
- Register error handlers via for centralized logging.
errorManager - Use for transient failures (network, API).
RetryManager - Use to protect against cascading failures.
CircuitBreaker - Check before retrying.
ConnectionError.retryable - Clean up error handlers in .
onDispose
- 使用特定错误类而非通用。
Error - 创建错误时包含上下文信息。
- 通过注册错误处理程序以实现集中式日志记录。
errorManager - 对瞬时故障(网络、API)使用。
RetryManager - 使用防止级联故障。
CircuitBreaker - 重试前检查属性。
ConnectionError.retryable - 在中清理错误处理程序。
onDispose