598 lines
13 KiB
Dart
598 lines
13 KiB
Dart
import 'dart:io';
|
||
|
||
/// Swagger CLI 基础异常类
|
||
abstract class SwaggerException implements Exception {
|
||
SwaggerException(this.message, {this.details}) : timestamp = DateTime.now();
|
||
final String message;
|
||
final String? details;
|
||
final DateTime timestamp;
|
||
|
||
@override
|
||
String toString() {
|
||
if (details != null) {
|
||
return '$runtimeType: $message\n详细信息: $details';
|
||
}
|
||
return '$runtimeType: $message';
|
||
}
|
||
}
|
||
|
||
/// Swagger解析异常
|
||
class SwaggerParseException extends SwaggerException {
|
||
SwaggerParseException(
|
||
super.message, {
|
||
super.details,
|
||
this.url,
|
||
this.statusCode,
|
||
this.operation,
|
||
});
|
||
final String? url;
|
||
final int? statusCode;
|
||
final String? operation;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('SwaggerParseException: $message');
|
||
|
||
if (url != null) {
|
||
buffer.writeln('URL: $url');
|
||
}
|
||
|
||
if (statusCode != null) {
|
||
buffer.writeln('状态码: $statusCode');
|
||
}
|
||
|
||
if (operation != null) {
|
||
buffer.writeln('操作: $operation');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 代码生成异常
|
||
class CodeGenerationException extends SwaggerException {
|
||
CodeGenerationException(
|
||
super.message, {
|
||
super.details,
|
||
this.generatorType,
|
||
this.modelName,
|
||
this.phase,
|
||
});
|
||
final String? generatorType;
|
||
final String? modelName;
|
||
final String? phase;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('CodeGenerationException: $message');
|
||
|
||
if (generatorType != null) {
|
||
buffer.writeln('生成器类型: $generatorType');
|
||
}
|
||
|
||
if (modelName != null) {
|
||
buffer.writeln('模型名称: $modelName');
|
||
}
|
||
|
||
if (phase != null) {
|
||
buffer.writeln('生成阶段: $phase');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 文件操作异常
|
||
class FileOperationException extends SwaggerException {
|
||
FileOperationException(
|
||
super.message, {
|
||
super.details,
|
||
this.filePath,
|
||
this.operation,
|
||
this.errorCode,
|
||
});
|
||
final String? filePath;
|
||
final String? operation;
|
||
final int? errorCode;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('FileOperationException: $message');
|
||
|
||
if (filePath != null) {
|
||
buffer.writeln('文件路径: $filePath');
|
||
}
|
||
|
||
if (operation != null) {
|
||
buffer.writeln('操作: $operation');
|
||
}
|
||
|
||
if (errorCode != null) {
|
||
buffer.writeln('错误代码: $errorCode');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 命令异常
|
||
class CommandException extends SwaggerException {
|
||
CommandException(
|
||
super.message, {
|
||
super.details,
|
||
this.commandName,
|
||
this.arguments,
|
||
this.exitCode,
|
||
});
|
||
final String? commandName;
|
||
final List<String>? arguments;
|
||
final int? exitCode;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('CommandException: $message');
|
||
|
||
if (commandName != null) {
|
||
buffer.writeln('命令: $commandName');
|
||
}
|
||
|
||
if (arguments != null && arguments!.isNotEmpty) {
|
||
buffer.writeln('参数: ${arguments!.join(' ')}');
|
||
}
|
||
|
||
if (exitCode != null) {
|
||
buffer.writeln('退出代码: $exitCode');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 验证异常
|
||
class ValidationException extends SwaggerException {
|
||
ValidationException(
|
||
super.message, {
|
||
super.details,
|
||
this.field,
|
||
this.value,
|
||
this.rule,
|
||
});
|
||
final String? field;
|
||
final dynamic value;
|
||
final String? rule;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('ValidationException: $message');
|
||
|
||
if (field != null) {
|
||
buffer.writeln('字段: $field');
|
||
}
|
||
|
||
if (value != null) {
|
||
buffer.writeln('值: $value');
|
||
}
|
||
|
||
if (rule != null) {
|
||
buffer.writeln('验证规则: $rule');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 配置异常
|
||
class ConfigurationException extends SwaggerException {
|
||
ConfigurationException(
|
||
super.message, {
|
||
super.details,
|
||
this.configKey,
|
||
this.configValue,
|
||
this.source,
|
||
});
|
||
final String? configKey;
|
||
final dynamic configValue;
|
||
final String? source;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('ConfigurationException: $message');
|
||
|
||
if (configKey != null) {
|
||
buffer.writeln('配置键: $configKey');
|
||
}
|
||
|
||
if (configValue != null) {
|
||
buffer.writeln('配置值: $configValue');
|
||
}
|
||
|
||
if (source != null) {
|
||
buffer.writeln('来源: $source');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 网络异常
|
||
class NetworkException extends SwaggerException {
|
||
NetworkException(
|
||
super.message, {
|
||
super.details,
|
||
this.url,
|
||
this.statusCode,
|
||
this.method,
|
||
this.timeout,
|
||
});
|
||
final String? url;
|
||
final int? statusCode;
|
||
final String? method;
|
||
final Duration? timeout;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('NetworkException: $message');
|
||
|
||
if (url != null) {
|
||
buffer.writeln('URL: $url');
|
||
}
|
||
|
||
if (method != null) {
|
||
buffer.writeln('方法: $method');
|
||
}
|
||
|
||
if (statusCode != null) {
|
||
buffer.writeln('状态码: $statusCode');
|
||
}
|
||
|
||
if (timeout != null) {
|
||
buffer.writeln('超时: ${timeout!.inSeconds}秒');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 缓存异常
|
||
class CacheException extends SwaggerException {
|
||
CacheException(
|
||
super.message, {
|
||
super.details,
|
||
this.cacheKey,
|
||
this.operation,
|
||
this.cacheType,
|
||
});
|
||
final String? cacheKey;
|
||
final String? operation;
|
||
final String? cacheType;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('CacheException: $message');
|
||
|
||
if (cacheKey != null) {
|
||
buffer.writeln('缓存键: $cacheKey');
|
||
}
|
||
|
||
if (operation != null) {
|
||
buffer.writeln('操作: $operation');
|
||
}
|
||
|
||
if (cacheType != null) {
|
||
buffer.writeln('缓存类型: $cacheType');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 性能异常
|
||
class PerformanceException extends SwaggerException {
|
||
PerformanceException(
|
||
super.message, {
|
||
super.details,
|
||
this.operation,
|
||
this.duration,
|
||
this.threshold,
|
||
});
|
||
final String? operation;
|
||
final Duration? duration;
|
||
final Duration? threshold;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('PerformanceException: $message');
|
||
|
||
if (operation != null) {
|
||
buffer.writeln('操作: $operation');
|
||
}
|
||
|
||
if (duration != null) {
|
||
buffer.writeln('耗时: ${duration!.inMilliseconds}ms');
|
||
}
|
||
|
||
if (threshold != null) {
|
||
buffer.writeln('阈值: ${threshold!.inMilliseconds}ms');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 类型异常
|
||
class TypeException extends SwaggerException {
|
||
TypeException(
|
||
super.message, {
|
||
super.details,
|
||
this.propertyName,
|
||
this.expectedType,
|
||
this.actualType,
|
||
this.value,
|
||
});
|
||
final String? propertyName;
|
||
final String? expectedType;
|
||
final String? actualType;
|
||
final dynamic value;
|
||
|
||
@override
|
||
String toString() {
|
||
final buffer = StringBuffer();
|
||
buffer.writeln('TypeException: $message');
|
||
|
||
if (propertyName != null) {
|
||
buffer.writeln('属性名: $propertyName');
|
||
}
|
||
|
||
if (expectedType != null) {
|
||
buffer.writeln('期望类型: $expectedType');
|
||
}
|
||
|
||
if (actualType != null) {
|
||
buffer.writeln('实际类型: $actualType');
|
||
}
|
||
|
||
if (value != null) {
|
||
buffer.writeln('值: $value');
|
||
}
|
||
|
||
if (details != null) {
|
||
buffer.writeln('详细信息: $details');
|
||
}
|
||
|
||
return buffer.toString().trim();
|
||
}
|
||
}
|
||
|
||
/// 异常处理器
|
||
class ExceptionHandler {
|
||
static final Map<Type, void Function(SwaggerException)> _handlers = {};
|
||
|
||
/// 注册异常处理器
|
||
static void register<T extends SwaggerException>(
|
||
void Function(T exception) handler,
|
||
) {
|
||
_handlers[T] = (exception) => handler(exception as T);
|
||
}
|
||
|
||
/// 处理异常
|
||
static void handle(SwaggerException exception) {
|
||
final handler = _handlers[exception.runtimeType];
|
||
if (handler != null) {
|
||
handler(exception);
|
||
} else {
|
||
// 默认处理
|
||
_defaultHandler(exception);
|
||
}
|
||
}
|
||
|
||
/// 默认异常处理
|
||
static void _defaultHandler(SwaggerException exception) {
|
||
print('🚨 异常: $exception');
|
||
print('时间: ${exception.timestamp.toIso8601String()}');
|
||
print('');
|
||
}
|
||
|
||
/// 记录异常到文件
|
||
static Future<void> logException(
|
||
SwaggerException exception, {
|
||
String? logFilePath,
|
||
}) async {
|
||
try {
|
||
final logFile = logFilePath != null
|
||
? File(logFilePath)
|
||
: File('swagger_cli_errors.log');
|
||
|
||
final logEntry = [
|
||
'[${'=' * 50}]',
|
||
'时间: ${exception.timestamp.toIso8601String()}',
|
||
'类型: ${exception.runtimeType}',
|
||
'消息: ${exception.message}',
|
||
if (exception.details != null) '详细信息: ${exception.details}',
|
||
'堆栈跟踪: ${StackTrace.current}',
|
||
'',
|
||
].join('\n');
|
||
|
||
await logFile.writeAsString(logEntry, mode: FileMode.append);
|
||
} catch (e) {
|
||
print('记录异常到文件失败: $e');
|
||
}
|
||
}
|
||
|
||
/// 清理异常处理器
|
||
static void clear() {
|
||
_handlers.clear();
|
||
}
|
||
}
|
||
|
||
/// 异常工厂
|
||
class ExceptionFactory {
|
||
/// 创建解析异常
|
||
static SwaggerParseException createParseException(
|
||
String message, {
|
||
String? url,
|
||
int? statusCode,
|
||
String? operation,
|
||
dynamic cause,
|
||
}) {
|
||
return SwaggerParseException(
|
||
message,
|
||
details: cause?.toString(),
|
||
url: url,
|
||
statusCode: statusCode,
|
||
operation: operation,
|
||
);
|
||
}
|
||
|
||
/// 创建代码生成异常
|
||
static CodeGenerationException createCodeGenerationException(
|
||
String message, {
|
||
String? generatorType,
|
||
String? modelName,
|
||
String? phase,
|
||
dynamic cause,
|
||
}) {
|
||
return CodeGenerationException(
|
||
message,
|
||
details: cause?.toString(),
|
||
generatorType: generatorType,
|
||
modelName: modelName,
|
||
phase: phase,
|
||
);
|
||
}
|
||
|
||
/// 创建文件操作异常
|
||
static FileOperationException createFileOperationException(
|
||
String message, {
|
||
String? filePath,
|
||
String? operation,
|
||
int? errorCode,
|
||
dynamic cause,
|
||
}) {
|
||
return FileOperationException(
|
||
message,
|
||
details: cause?.toString(),
|
||
filePath: filePath,
|
||
operation: operation,
|
||
errorCode: errorCode,
|
||
);
|
||
}
|
||
|
||
/// 创建验证异常
|
||
static ValidationException createValidationException(
|
||
String message, {
|
||
String? field,
|
||
dynamic value,
|
||
String? rule,
|
||
dynamic cause,
|
||
}) {
|
||
return ValidationException(
|
||
message,
|
||
details: cause?.toString(),
|
||
field: field,
|
||
value: value,
|
||
rule: rule,
|
||
);
|
||
}
|
||
|
||
/// 创建网络异常
|
||
static NetworkException createNetworkException(
|
||
String message, {
|
||
String? url,
|
||
int? statusCode,
|
||
String? method,
|
||
Duration? timeout,
|
||
dynamic cause,
|
||
}) {
|
||
return NetworkException(
|
||
message,
|
||
details: cause?.toString(),
|
||
url: url,
|
||
statusCode: statusCode,
|
||
method: method,
|
||
timeout: timeout,
|
||
);
|
||
}
|
||
|
||
/// 从标准异常创建
|
||
static SwaggerException fromStandardException(
|
||
Exception exception, {
|
||
String? context,
|
||
}) {
|
||
if (exception is FileSystemException) {
|
||
return FileOperationException(
|
||
'文件系统错误',
|
||
details: exception.message,
|
||
filePath: exception.path,
|
||
operation: context,
|
||
);
|
||
} else if (exception is SocketException) {
|
||
return NetworkException(
|
||
'网络连接错误',
|
||
details: exception.message,
|
||
url: context,
|
||
);
|
||
} else if (exception is FormatException) {
|
||
return SwaggerParseException(
|
||
'格式错误',
|
||
details: exception.message,
|
||
operation: context,
|
||
);
|
||
} else {
|
||
return GeneralSwaggerException(
|
||
'未知错误',
|
||
details: exception.toString(),
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 通用Swagger异常(当无法确定具体类型时使用)
|
||
class GeneralSwaggerException extends SwaggerException {
|
||
GeneralSwaggerException(super.message, {super.details});
|
||
}
|