import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; /// 错误类型枚举 enum ErrorType { network, authentication, validation, server, unknown, } /// 错误严重程度枚举 enum ErrorSeverity { info, warning, error, critical, } /// 应用错误模型 class AppError { final String id; final String message; final String? details; final ErrorType type; final ErrorSeverity severity; final DateTime timestamp; final String? stackTrace; final Map? context; const AppError({ required this.id, required this.message, this.details, required this.type, required this.severity, required this.timestamp, this.stackTrace, this.context, }); AppError copyWith({ String? id, String? message, String? details, ErrorType? type, ErrorSeverity? severity, DateTime? timestamp, String? stackTrace, Map? context, }) { return AppError( id: id ?? this.id, message: message ?? this.message, details: details ?? this.details, type: type ?? this.type, severity: severity ?? this.severity, timestamp: timestamp ?? this.timestamp, stackTrace: stackTrace ?? this.stackTrace, context: context ?? this.context, ); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is AppError && other.id == id && other.message == message && other.type == type && other.severity == severity; } @override int get hashCode { return id.hashCode ^ message.hashCode ^ type.hashCode ^ severity.hashCode; } @override String toString() { return 'AppError(id: $id, message: $message, type: $type, severity: $severity, timestamp: $timestamp)'; } /// 创建网络错误 factory AppError.network(String message, {String? details, Map? context}) { return AppError( id: DateTime.now().millisecondsSinceEpoch.toString(), message: message, details: details, type: ErrorType.network, severity: ErrorSeverity.error, timestamp: DateTime.now(), context: context, ); } /// 创建认证错误 factory AppError.authentication(String message, {String? details, Map? context}) { return AppError( id: DateTime.now().millisecondsSinceEpoch.toString(), message: message, details: details, type: ErrorType.authentication, severity: ErrorSeverity.error, timestamp: DateTime.now(), context: context, ); } /// 创建验证错误 factory AppError.validation(String message, {String? details, Map? context}) { return AppError( id: DateTime.now().millisecondsSinceEpoch.toString(), message: message, details: details, type: ErrorType.validation, severity: ErrorSeverity.warning, timestamp: DateTime.now(), context: context, ); } /// 创建服务器错误 factory AppError.server(String message, {String? details, Map? context}) { return AppError( id: DateTime.now().millisecondsSinceEpoch.toString(), message: message, details: details, type: ErrorType.server, severity: ErrorSeverity.error, timestamp: DateTime.now(), context: context, ); } /// 创建未知错误 factory AppError.unknown(String message, {String? details, String? stackTrace, Map? context}) { return AppError( id: DateTime.now().millisecondsSinceEpoch.toString(), message: message, details: details, type: ErrorType.unknown, severity: ErrorSeverity.error, timestamp: DateTime.now(), stackTrace: stackTrace, context: context, ); } } /// 错误状态模型 class ErrorState { final List errors; final AppError? currentError; const ErrorState({ required this.errors, this.currentError, }); bool get hasErrors => errors.isNotEmpty; ErrorState copyWith({ List? errors, AppError? currentError, }) { return ErrorState( errors: errors ?? this.errors, currentError: currentError, ); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is ErrorState && other.errors.length == errors.length && other.currentError == currentError; } @override int get hashCode { return errors.hashCode ^ currentError.hashCode; } } /// 错误管理Provider class ErrorNotifier extends StateNotifier { static const int maxErrorCount = 50; // 最大错误数量 static const Duration errorRetentionDuration = Duration(hours: 24); // 错误保留时间 ErrorNotifier() : super(const ErrorState(errors: [])); /// 添加错误 void addError(AppError error) { final updatedErrors = List.from(state.errors); updatedErrors.insert(0, error); // 新错误插入到列表开头 // 限制错误数量 if (updatedErrors.length > maxErrorCount) { updatedErrors.removeRange(maxErrorCount, updatedErrors.length); } // 清理过期错误 _cleanExpiredErrors(updatedErrors); state = state.copyWith( errors: updatedErrors, currentError: error, ); // 在调试模式下打印错误 if (kDebugMode) { print('Error added: ${error.toString()}'); if (error.stackTrace != null) { print('Stack trace: ${error.stackTrace}'); } } } /// 清除当前错误 void clearCurrentError() { state = state.copyWith(currentError: null); } /// 清除指定错误 void removeError(String errorId) { final updatedErrors = state.errors.where((error) => error.id != errorId).toList(); AppError? newCurrentError = state.currentError; if (state.currentError?.id == errorId) { newCurrentError = null; } state = state.copyWith( errors: updatedErrors, currentError: newCurrentError, ); } /// 清除所有错误 void clearAllErrors() { state = const ErrorState(errors: []); } /// 清除指定类型的错误 void clearErrorsByType(ErrorType type) { final updatedErrors = state.errors.where((error) => error.type != type).toList(); AppError? newCurrentError = state.currentError; if (state.currentError?.type == type) { newCurrentError = null; } state = state.copyWith( errors: updatedErrors, currentError: newCurrentError, ); } /// 清除指定严重程度的错误 void clearErrorsBySeverity(ErrorSeverity severity) { final updatedErrors = state.errors.where((error) => error.severity != severity).toList(); AppError? newCurrentError = state.currentError; if (state.currentError?.severity == severity) { newCurrentError = null; } state = state.copyWith( errors: updatedErrors, currentError: newCurrentError, ); } /// 获取指定类型的错误 List getErrorsByType(ErrorType type) { return state.errors.where((error) => error.type == type).toList(); } /// 获取指定严重程度的错误 List getErrorsBySeverity(ErrorSeverity severity) { return state.errors.where((error) => error.severity == severity).toList(); } /// 获取最近的错误 List getRecentErrors({int count = 10}) { return state.errors.take(count).toList(); } /// 检查是否有指定类型的错误 bool hasErrorOfType(ErrorType type) { return state.errors.any((error) => error.type == type); } /// 检查是否有指定严重程度的错误 bool hasErrorOfSeverity(ErrorSeverity severity) { return state.errors.any((error) => error.severity == severity); } /// 清理过期错误 void _cleanExpiredErrors(List errors) { final now = DateTime.now(); errors.removeWhere((error) => now.difference(error.timestamp) > errorRetentionDuration); } /// 处理异常并转换为AppError void handleException(dynamic exception, { String? message, ErrorType? type, ErrorSeverity? severity, Map? context, }) { String errorMessage = message ?? exception.toString(); ErrorType errorType = type ?? ErrorType.unknown; ErrorSeverity errorSeverity = severity ?? ErrorSeverity.error; String? stackTrace; if (exception is Error) { stackTrace = exception.stackTrace?.toString(); } final error = AppError( id: DateTime.now().millisecondsSinceEpoch.toString(), message: errorMessage, details: exception.toString(), type: errorType, severity: errorSeverity, timestamp: DateTime.now(), stackTrace: stackTrace, context: context, ); addError(error); } } /// 错误状态Provider final errorProvider = StateNotifierProvider( (ref) => ErrorNotifier(), ); /// 当前错误Provider final currentErrorProvider = Provider( (ref) => ref.watch(errorProvider).currentError, ); /// 是否有错误Provider final hasErrorsProvider = Provider( (ref) => ref.watch(errorProvider).hasErrors, ); /// 错误数量Provider final errorCountProvider = Provider( (ref) => ref.watch(errorProvider).errors.length, ); /// 网络错误Provider final networkErrorsProvider = Provider>( (ref) => ref.watch(errorProvider).errors .where((error) => error.type == ErrorType.network) .toList(), ); /// 认证错误Provider final authErrorsProvider = Provider>( (ref) => ref.watch(errorProvider).errors .where((error) => error.type == ErrorType.authentication) .toList(), ); /// 严重错误Provider final criticalErrorsProvider = Provider>( (ref) => ref.watch(errorProvider).errors .where((error) => error.severity == ErrorSeverity.critical) .toList(), );