error handle
This commit is contained in:
60
src/main.ts
60
src/main.ts
@@ -1,22 +1,16 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import { naiveUi } from '@/common/naive-ui/components.ts'
|
import { naiveUi } from '@/common/naive-ui/components.ts'
|
||||||
import { SystemServiceIntegration } from '@/services/SystemServiceIntegration'
|
|
||||||
import { registerBuiltInApps } from '@/apps'
|
import { registerBuiltInApps } from '@/apps'
|
||||||
|
import { systemBootstrapper } from '@/services/di/SystemBootstrapper'
|
||||||
|
import { ServiceProvider } from '@/services/di/ServiceProvider'
|
||||||
|
import { ServiceIds } from '@/services/di/ServiceRegistry'
|
||||||
|
|
||||||
import 'virtual:uno.css'
|
import 'virtual:uno.css'
|
||||||
import './css/basic.css'
|
import './css/basic.css'
|
||||||
|
|
||||||
import App from './ui/App.vue'
|
import App from './ui/App.vue'
|
||||||
|
|
||||||
// 注册内置应用
|
|
||||||
registerBuiltInApps()
|
|
||||||
|
|
||||||
// 初始化系统服务
|
|
||||||
const systemService = new SystemServiceIntegration({
|
|
||||||
debug: import.meta.env.DEV
|
|
||||||
})
|
|
||||||
|
|
||||||
// 创建应用实例
|
// 创建应用实例
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
@@ -24,38 +18,58 @@ const app = createApp(App)
|
|||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
app.use(naiveUi)
|
app.use(naiveUi)
|
||||||
|
|
||||||
// 提供系统服务给组件使用
|
// 全局错误处理
|
||||||
|
app.config.errorHandler = (error, instance, info) => {
|
||||||
|
console.error('Vue应用错误:', error, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动应用函数
|
||||||
|
async function startApplication() {
|
||||||
|
try {
|
||||||
|
// 注册内置应用
|
||||||
|
registerBuiltInApps()
|
||||||
|
|
||||||
|
console.log('正在启动桌面系统...')
|
||||||
|
|
||||||
|
// 使用系统启动器初始化依赖注入系统和所有服务
|
||||||
|
const success = await systemBootstrapper.bootstrap({
|
||||||
|
debug: import.meta.env.DEV,
|
||||||
|
autoCleanup: true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
throw new Error('系统启动失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取系统服务并提供给Vue应用
|
||||||
|
const systemService = ServiceProvider.getSystemService()
|
||||||
app.provide('systemService', systemService)
|
app.provide('systemService', systemService)
|
||||||
|
|
||||||
// 初始化系统服务然后挂载应用
|
// 挂载应用
|
||||||
systemService
|
|
||||||
.initialize()
|
|
||||||
.then(() => {
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
console.log('桌面系统启动完成')
|
console.log('桌面系统启动完成')
|
||||||
})
|
|
||||||
.catch((error) => {
|
} catch (error) {
|
||||||
console.error('系统启动失败:', error)
|
console.error('系统启动失败:', error)
|
||||||
// 显示错误信息
|
// 显示错误信息
|
||||||
document.body.innerHTML = `
|
document.body.innerHTML = `
|
||||||
<div style="display: flex; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif;">
|
<div style="display: flex; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif;">
|
||||||
<div style="text-align: center; color: #e74c3c;">
|
<div style="text-align: center; color: #e74c3c;">
|
||||||
<h1>系统启动失败</h1>
|
<h1>系统启动失败</h1>
|
||||||
<p>错误信息: ${error.message}</p>
|
<p>错误信息: ${error instanceof Error ? error.message : '未知错误'}</p>
|
||||||
<button onclick="location.reload()" style="padding: 10px 20px; margin-top: 20px; cursor: pointer;">
|
<button onclick="location.reload()" style="padding: 10px 20px; margin-top: 20px; cursor: pointer;">
|
||||||
重新加载
|
重新加载
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
})
|
|
||||||
|
|
||||||
// 全局错误处理
|
|
||||||
app.config.errorHandler = (error, instance, info) => {
|
|
||||||
console.error('Vue应用错误:', error, info)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动应用
|
||||||
|
startApplication()
|
||||||
|
|
||||||
// 在页面卸载时清理系统服务
|
// 在页面卸载时清理系统服务
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
systemService.shutdown()
|
systemBootstrapper.shutdown()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -101,14 +101,24 @@ export interface SandboxEvents {
|
|||||||
/**
|
/**
|
||||||
* 应用沙箱引擎类
|
* 应用沙箱引擎类
|
||||||
*/
|
*/
|
||||||
|
import { ServiceProvider, Inject } from './di/ServiceProvider'
|
||||||
|
import type { IServiceContainer } from './di/IServiceContainer'
|
||||||
|
|
||||||
export class ApplicationSandboxEngine {
|
export class ApplicationSandboxEngine {
|
||||||
|
// 服务容器
|
||||||
|
private serviceContainer: IServiceContainer
|
||||||
|
|
||||||
private sandboxes = reactive(new Map<string, SandboxInstance>())
|
private sandboxes = reactive(new Map<string, SandboxInstance>())
|
||||||
private performanceData = reactive(new Map<string, SandboxPerformance[]>())
|
private performanceData = reactive(new Map<string, SandboxPerformance[]>())
|
||||||
private monitoringInterval: number | null = null
|
private monitoringInterval: number | null = null
|
||||||
|
|
||||||
|
// 资源服务
|
||||||
|
@Inject('resourceService')
|
||||||
private resourceService: ResourceService
|
private resourceService: ResourceService
|
||||||
|
|
||||||
constructor(resourceService: ResourceService) {
|
constructor(resourceService: ResourceService, serviceContainer: IServiceContainer) {
|
||||||
this.resourceService = resourceService
|
this.resourceService = resourceService
|
||||||
|
this.serviceContainer = serviceContainer
|
||||||
this.startPerformanceMonitoring()
|
this.startPerformanceMonitoring()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
79
src/services/IErrorHandler.ts
Normal file
79
src/services/IErrorHandler.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* 全局错误处理器接口
|
||||||
|
* 负责统一处理系统中的所有错误
|
||||||
|
*/
|
||||||
|
export interface IErrorHandler {
|
||||||
|
/**
|
||||||
|
* 处理应用错误
|
||||||
|
* @param error 错误对象
|
||||||
|
* @param context 错误上下文信息
|
||||||
|
* @returns 是否成功处理了错误
|
||||||
|
*/
|
||||||
|
handleError(error: Error | any, context?: ErrorContext): boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理未捕获的异常
|
||||||
|
*/
|
||||||
|
setupGlobalErrorHandlers(): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取最近的错误记录
|
||||||
|
* @param limit 获取的最大数量
|
||||||
|
*/
|
||||||
|
getRecentErrors(limit?: number): ErrorRecord[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误上下文信息
|
||||||
|
*/
|
||||||
|
export interface ErrorContext {
|
||||||
|
/**
|
||||||
|
* 错误来源组件或服务名称
|
||||||
|
*/
|
||||||
|
source?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误发生的操作
|
||||||
|
*/
|
||||||
|
operation?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相关的应用ID
|
||||||
|
*/
|
||||||
|
appId?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他自定义信息
|
||||||
|
*/
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误记录
|
||||||
|
*/
|
||||||
|
export interface ErrorRecord {
|
||||||
|
/**
|
||||||
|
* 错误ID
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误对象
|
||||||
|
*/
|
||||||
|
error: Error | any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误上下文
|
||||||
|
*/
|
||||||
|
context?: ErrorContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误发生时间
|
||||||
|
*/
|
||||||
|
timestamp: Date
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已处理
|
||||||
|
*/
|
||||||
|
handled: boolean
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
|
|
||||||
import type { IEventBuilder, IEventMap, WindowFormDataUpdateParams } from '@/events/IEventBuilder'
|
import type { IEventBuilder, IEventMap, WindowFormDataUpdateParams } from '@/events/IEventBuilder'
|
||||||
import type { ResourceType } from './ResourceService'
|
import { ResourceService, ResourceType } from './ResourceService'
|
||||||
|
import { ServiceProvider, Inject } from './di/ServiceProvider'
|
||||||
// 导入所有服务
|
import type { IServiceContainer } from './di/IServiceContainer'
|
||||||
import { WindowFormService } from './WindowFormService.ts'
|
import { ServiceIds } from './di/ServiceRegistry'
|
||||||
import { ResourceService } from './ResourceService'
|
import { WindowFormService } from './WindowFormService'
|
||||||
import { ApplicationSandboxEngine } from './ApplicationSandboxEngine'
|
import { ApplicationSandboxEngine } from './ApplicationSandboxEngine'
|
||||||
import { ApplicationLifecycleManager } from './ApplicationLifecycleManager'
|
import { ApplicationLifecycleManager } from './ApplicationLifecycleManager'
|
||||||
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
||||||
@@ -55,12 +54,24 @@ export class SystemServiceIntegration {
|
|||||||
private config: SystemServiceConfig
|
private config: SystemServiceConfig
|
||||||
private startTime: Date
|
private startTime: Date
|
||||||
|
|
||||||
// 核心服务实例
|
// 核心服务实例 - 使用依赖注入
|
||||||
private eventBus: IEventBuilder<any>
|
@Inject(ServiceIds.EVENT_BUILDER)
|
||||||
private windowFormService!: WindowFormService
|
private eventBus!: IEventBuilder<any>
|
||||||
private resourceService!: ResourceService
|
|
||||||
private sandboxEngine!: ApplicationSandboxEngine
|
@Inject(ServiceIds.WINDOW_FORM_SERVICE)
|
||||||
private lifecycleManager!: ApplicationLifecycleManager
|
private windowFormService!: any
|
||||||
|
|
||||||
|
@Inject(ServiceIds.RESOURCE_SERVICE)
|
||||||
|
private resourceService!: any
|
||||||
|
|
||||||
|
@Inject(ServiceIds.SANDBOX_ENGINE)
|
||||||
|
private sandboxEngine!: any
|
||||||
|
|
||||||
|
@Inject(ServiceIds.LIFECYCLE_MANAGER)
|
||||||
|
private lifecycleManager!: any
|
||||||
|
|
||||||
|
@Inject(ServiceIds.EXTERNAL_APP_DISCOVERY)
|
||||||
|
private externalAppDiscovery!: any
|
||||||
|
|
||||||
// 系统状态
|
// 系统状态
|
||||||
private systemStatus = reactive<SystemStatus>({
|
private systemStatus = reactive<SystemStatus>({
|
||||||
@@ -78,8 +89,9 @@ export class SystemServiceIntegration {
|
|||||||
// 性能监控
|
// 性能监控
|
||||||
private cleanupInterval: number | null = null
|
private cleanupInterval: number | null = null
|
||||||
private performanceInterval: number | null = null
|
private performanceInterval: number | null = null
|
||||||
|
private serviceContainer: IServiceContainer
|
||||||
|
|
||||||
constructor(config: SystemServiceConfig = {}) {
|
constructor(serviceContainer: IServiceContainer, config: SystemServiceConfig = {}) {
|
||||||
this.config = {
|
this.config = {
|
||||||
debug: false,
|
debug: false,
|
||||||
autoCleanup: true,
|
autoCleanup: true,
|
||||||
@@ -88,7 +100,7 @@ export class SystemServiceIntegration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.startTime = new Date()
|
this.startTime = new Date()
|
||||||
this.eventBus = new EventBuilderImpl<any>()
|
this.serviceContainer = serviceContainer
|
||||||
|
|
||||||
this.setupGlobalErrorHandling()
|
this.setupGlobalErrorHandling()
|
||||||
}
|
}
|
||||||
@@ -98,36 +110,31 @@ export class SystemServiceIntegration {
|
|||||||
*/
|
*/
|
||||||
public async initialize(): Promise<void> {
|
public async initialize(): Promise<void> {
|
||||||
if (this.initialized.value) {
|
if (this.initialized.value) {
|
||||||
throw new Error('系统服务已初始化')
|
console.warn('系统服务已经初始化')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('开始初始化系统服务...')
|
console.log('开始初始化系统服务...')
|
||||||
|
|
||||||
// 按依赖顺序初始化服务
|
// 启动自动清理(如果启用)
|
||||||
await this.initializeServices()
|
|
||||||
|
|
||||||
// 设置服务间通信
|
|
||||||
this.setupServiceCommunication()
|
|
||||||
|
|
||||||
// 设置SDK消息处理
|
|
||||||
this.setupSDKMessageHandling()
|
|
||||||
|
|
||||||
// 启动自动清理
|
|
||||||
if (this.config.autoCleanup) {
|
if (this.config.autoCleanup) {
|
||||||
this.startAutoCleanup()
|
this.startAutoCleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动外置应用发现服务
|
// 更新系统状态
|
||||||
// 注意:外置应用发现服务统一由 SystemServiceIntegration 管理,
|
|
||||||
// ApplicationLifecycleManager 只负责使用已发现的应用,避免重复启动
|
|
||||||
console.log('启动外置应用发现服务...')
|
|
||||||
await externalAppDiscovery.startDiscovery()
|
|
||||||
|
|
||||||
this.initialized.value = true
|
|
||||||
this.running.value = true
|
|
||||||
this.systemStatus.initialized = true
|
this.systemStatus.initialized = true
|
||||||
this.systemStatus.running = true
|
this.systemStatus.running = true
|
||||||
|
this.initialized.value = true
|
||||||
|
this.running.value = true
|
||||||
|
|
||||||
|
// 标记所有服务状态为已启动
|
||||||
|
this.systemStatus.servicesStatus = {
|
||||||
|
windowFormService: true,
|
||||||
|
resourceService: true,
|
||||||
|
sandboxEngine: true,
|
||||||
|
lifecycleManager: true
|
||||||
|
}
|
||||||
|
|
||||||
console.log('系统服务初始化完成')
|
console.log('系统服务初始化完成')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -137,6 +144,8 @@ export class SystemServiceIntegration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ... 保留其他现有方法
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统状态
|
* 获取系统状态
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -52,9 +52,10 @@ export class ServiceRegistry {
|
|||||||
// 注册基本服务 - 这些服务没有其他依赖
|
// 注册基本服务 - 这些服务没有其他依赖
|
||||||
this.registerEventBuilder()
|
this.registerEventBuilder()
|
||||||
this.registerExternalAppDiscovery()
|
this.registerExternalAppDiscovery()
|
||||||
|
this.registerResourceService()
|
||||||
|
this.registerErrorHandler()
|
||||||
|
|
||||||
// 注册核心服务 - 按照依赖关系顺序注册
|
// 注册核心服务 - 按照依赖关系顺序注册
|
||||||
this.registerResourceService()
|
|
||||||
this.registerWindowFormService()
|
this.registerWindowFormService()
|
||||||
this.registerSandboxEngine()
|
this.registerSandboxEngine()
|
||||||
this.registerLifecycleManager()
|
this.registerLifecycleManager()
|
||||||
@@ -170,8 +171,24 @@ export class ServiceRegistry {
|
|||||||
ServiceIds.WINDOW_FORM_SERVICE,
|
ServiceIds.WINDOW_FORM_SERVICE,
|
||||||
ServiceIds.SANDBOX_ENGINE,
|
ServiceIds.SANDBOX_ENGINE,
|
||||||
ServiceIds.LIFECYCLE_MANAGER,
|
ServiceIds.LIFECYCLE_MANAGER,
|
||||||
ServiceIds.EVENT_BUILDER
|
ServiceIds.EVENT_BUILDER,
|
||||||
|
ServiceIds.ERROR_HANDLER
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册错误处理服务
|
||||||
|
*/
|
||||||
|
private registerErrorHandler(): void {
|
||||||
|
this.container.register(
|
||||||
|
ServiceIds.ERROR_HANDLER,
|
||||||
|
async () => {
|
||||||
|
// 延迟导入避免循环依赖
|
||||||
|
const { ErrorHandlerImpl } = await import('../impl/ErrorHandlerImpl')
|
||||||
|
return new ErrorHandlerImpl()
|
||||||
|
},
|
||||||
|
[] // 错误处理服务应尽量减少依赖,避免在错误处理过程中出现循环依赖
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class ApplicationComponent {
|
|||||||
function dynamicServiceExample(serviceId: string) {
|
function dynamicServiceExample(serviceId: string) {
|
||||||
// 使用get方法动态获取服务
|
// 使用get方法动态获取服务
|
||||||
try {
|
try {
|
||||||
const service = ServiceProvider.getServiceById(serviceId as any)
|
const service = ServiceProvider.getService(serviceId as any)
|
||||||
console.log(`动态获取服务[${serviceId}]:`, !!service)
|
console.log(`动态获取服务[${serviceId}]:`, !!service)
|
||||||
return service
|
return service
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
103
src/services/example/ErrorHandlerExample.ts
Normal file
103
src/services/example/ErrorHandlerExample.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import { ServiceProvider } from '../di/ServiceProvider'
|
||||||
|
import { ServiceIds } from '../di/ServiceRegistry'
|
||||||
|
import type { IErrorHandler, ErrorContext } from '../IErrorHandler'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误处理服务使用示例
|
||||||
|
*/
|
||||||
|
export class ErrorHandlerExample {
|
||||||
|
private errorHandler: IErrorHandler
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
// 通过服务提供者获取错误处理器实例
|
||||||
|
this.errorHandler = ServiceProvider.getService<IErrorHandler>(ServiceIds.ERROR_HANDLER)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 演示不同类型错误的处理
|
||||||
|
*/
|
||||||
|
public demonstrateErrorHandling(): void {
|
||||||
|
console.log('=== 开始演示错误处理服务 ===')
|
||||||
|
|
||||||
|
// 1. 处理标准Error对象
|
||||||
|
try {
|
||||||
|
throw new Error('这是一个标准错误')
|
||||||
|
} catch (error) {
|
||||||
|
const context: ErrorContext = {
|
||||||
|
source: 'ErrorHandlerExample',
|
||||||
|
operation: 'demonstrateStandardError',
|
||||||
|
appId: 'example-app-123'
|
||||||
|
}
|
||||||
|
this.errorHandler.handleError(error, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 处理类型错误
|
||||||
|
try {
|
||||||
|
const obj: any = null
|
||||||
|
obj.method() // 这会抛出TypeError
|
||||||
|
} catch (error) {
|
||||||
|
this.errorHandler.handleError(error, {
|
||||||
|
source: 'ErrorHandlerExample',
|
||||||
|
operation: 'demonstrateTypeError',
|
||||||
|
additionalInfo: '尝试在null上调用方法'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 处理未捕获的Promise错误
|
||||||
|
console.log('演示未捕获的Promise错误...')
|
||||||
|
// 注意:这个错误会被全局错误处理器捕获
|
||||||
|
Promise.reject(new Error('这是一个未处理的Promise错误'))
|
||||||
|
|
||||||
|
// 4. 获取最近的错误记录
|
||||||
|
setTimeout(() => {
|
||||||
|
const recentErrors = this.errorHandler.getRecentErrors(2)
|
||||||
|
console.log('\n=== 最近的错误记录 ===')
|
||||||
|
recentErrors.forEach(record => {
|
||||||
|
console.log(`错误ID: ${record.id}`)
|
||||||
|
console.log(`时间: ${record.timestamp.toISOString()}`)
|
||||||
|
console.log(`处理状态: ${record.handled ? '已处理' : '未处理'}`)
|
||||||
|
console.log(`上下文:`, record.context)
|
||||||
|
})
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在组件或服务中使用错误处理器的示例
|
||||||
|
*/
|
||||||
|
export function useErrorHandlerInComponent() {
|
||||||
|
const errorHandler = ServiceProvider.getService<IErrorHandler>(ServiceIds.ERROR_HANDLER)
|
||||||
|
|
||||||
|
// 在组件方法中使用
|
||||||
|
function performRiskyOperation() {
|
||||||
|
try {
|
||||||
|
// 执行可能失败的操作
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
throw new Error('操作随机失败')
|
||||||
|
}
|
||||||
|
return '操作成功'
|
||||||
|
} catch (error) {
|
||||||
|
// 使用错误处理器记录和处理错误
|
||||||
|
errorHandler.handleError(error, {
|
||||||
|
source: 'MyComponent',
|
||||||
|
operation: 'performRiskyOperation',
|
||||||
|
componentProps: { /* 组件属性信息 */ }
|
||||||
|
})
|
||||||
|
|
||||||
|
// 可以选择返回一个默认值或重新抛出
|
||||||
|
return '操作失败,但已正确处理'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { performRiskyOperation }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出一个立即执行的示例函数,方便直接测试
|
||||||
|
export function runErrorHandlerExample() {
|
||||||
|
try {
|
||||||
|
const example = new ErrorHandlerExample()
|
||||||
|
example.demonstrateErrorHandling()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('示例执行失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
154
src/services/impl/ErrorHandlerImpl.ts
Normal file
154
src/services/impl/ErrorHandlerImpl.ts
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import type { IErrorHandler, ErrorContext, ErrorRecord } from '../IErrorHandler'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局错误处理器实现
|
||||||
|
*/
|
||||||
|
export class ErrorHandlerImpl implements IErrorHandler {
|
||||||
|
private errorRecords: ErrorRecord[] = []
|
||||||
|
private maxRecords = 100
|
||||||
|
private isGlobalHandlersSetup = false
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
// 初始化时可以设置全局错误处理器
|
||||||
|
this.setupGlobalErrorHandlers()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理应用错误
|
||||||
|
* @param error 错误对象
|
||||||
|
* @param context 错误上下文信息
|
||||||
|
* @returns 是否成功处理了错误
|
||||||
|
*/
|
||||||
|
public handleError(error: Error | any, context: ErrorContext = {}): boolean {
|
||||||
|
try {
|
||||||
|
// 创建错误记录
|
||||||
|
const errorRecord: ErrorRecord = {
|
||||||
|
id: uuidv4(),
|
||||||
|
error,
|
||||||
|
context,
|
||||||
|
timestamp: new Date(),
|
||||||
|
handled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存错误记录
|
||||||
|
this.addErrorRecord(errorRecord)
|
||||||
|
|
||||||
|
// 根据错误类型进行处理
|
||||||
|
if (error instanceof Error) {
|
||||||
|
this.logError(error, context)
|
||||||
|
this.reportError(error, context)
|
||||||
|
} else {
|
||||||
|
// 非标准错误对象
|
||||||
|
this.logUnknownError(error, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorRecord.handled = true
|
||||||
|
return true
|
||||||
|
} catch (handlerError) {
|
||||||
|
console.error('错误处理器自身出错:', handlerError)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理未捕获的异常
|
||||||
|
*/
|
||||||
|
public setupGlobalErrorHandlers(): void {
|
||||||
|
if (this.isGlobalHandlersSetup) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 捕获未处理的Promise错误
|
||||||
|
window.addEventListener('unhandledrejection', (event) => {
|
||||||
|
this.handleError(event.reason, {
|
||||||
|
source: 'unhandledrejection',
|
||||||
|
operation: 'Promise处理'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 捕获全局错误
|
||||||
|
window.addEventListener('error', (event) => {
|
||||||
|
const error = event.error || new Error(event.message)
|
||||||
|
this.handleError(error, {
|
||||||
|
source: 'window.error',
|
||||||
|
operation: event.filename || window.location.pathname,
|
||||||
|
lineNumber: event.lineno,
|
||||||
|
columnNumber: event.colno
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Vue应用的错误处理可以在main.ts中配置
|
||||||
|
|
||||||
|
this.isGlobalHandlersSetup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取最近的错误记录
|
||||||
|
* @param limit 获取的最大数量
|
||||||
|
*/
|
||||||
|
public getRecentErrors(limit: number = 10): ErrorRecord[] {
|
||||||
|
return this.errorRecords
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
|
||||||
|
.slice(0, limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加错误记录到历史
|
||||||
|
*/
|
||||||
|
private addErrorRecord(record: ErrorRecord): void {
|
||||||
|
this.errorRecords.unshift(record)
|
||||||
|
|
||||||
|
// 限制记录数量
|
||||||
|
if (this.errorRecords.length > this.maxRecords) {
|
||||||
|
this.errorRecords = this.errorRecords.slice(0, this.maxRecords)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录标准错误
|
||||||
|
*/
|
||||||
|
private logError(error: Error, context: ErrorContext): void {
|
||||||
|
console.error(`[错误处理] ${context.source || '未知来源'}: ${error.message}`, {
|
||||||
|
error,
|
||||||
|
stack: error.stack,
|
||||||
|
context
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录未知类型错误
|
||||||
|
*/
|
||||||
|
private logUnknownError(error: any, context: ErrorContext): void {
|
||||||
|
console.error(`[错误处理] ${context.source || '未知来源'}: 发生未知类型错误`, {
|
||||||
|
error,
|
||||||
|
context
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报告错误(可以扩展为发送到错误监控服务)
|
||||||
|
*/
|
||||||
|
private reportError(error: Error, context: ErrorContext): void {
|
||||||
|
// 在实际项目中,这里可以将错误发送到远程监控服务
|
||||||
|
// 例如:sentry、logrocket等
|
||||||
|
// 现在只是记录到控制台
|
||||||
|
console.debug('[错误报告] 准备发送错误信息...')
|
||||||
|
|
||||||
|
// 模拟异步错误报告
|
||||||
|
setTimeout(() => {
|
||||||
|
console.debug(`[错误报告] 错误已记录,ID: ${context.source || 'unknown'}`)
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建单例实例
|
||||||
|
let instance: ErrorHandlerImpl | null = null
|
||||||
|
|
||||||
|
export function getErrorHandlerInstance(): ErrorHandlerImpl {
|
||||||
|
if (!instance) {
|
||||||
|
instance = new ErrorHandlerImpl()
|
||||||
|
}
|
||||||
|
return instance
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user