swagger_generator_flutter/lib/core/exceptions.dart

479 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:io';
import 'package:swagger_generator_flutter/utils/logger.dart';
String _formatExceptionDetails(
String header,
Map<String, Object?> fields,
) {
final buffer = StringBuffer()..writeln(header);
fields.forEach((label, value) {
if (value != null) {
buffer.writeln('$label: $value');
}
});
return buffer.toString().trim();
}
/// 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() => _formatExceptionDetails(
'SwaggerParseException: $message',
{
'URL': url,
'状态码': statusCode,
'操作': operation,
'详细信息': details,
},
);
}
/// 代码生成异常
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() => _formatExceptionDetails(
'CodeGenerationException: $message',
{
'生成器类型': generatorType,
'模型名称': modelName,
'生成阶段': phase,
'详细信息': details,
},
);
}
/// 文件操作异常
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() => _formatExceptionDetails(
'FileOperationException: $message',
{
'文件路径': filePath,
'操作': operation,
'错误代码': errorCode,
'详细信息': details,
},
);
}
/// 命令异常
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() => _formatExceptionDetails(
'CommandException: $message',
{
'命令': commandName,
'参数': arguments?.join(' '),
'退出代码': exitCode,
'详细信息': details,
},
);
}
/// 验证异常
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() => _formatExceptionDetails(
'ValidationException: $message',
{
'字段': field,
'': value,
'验证规则': rule,
'详细信息': details,
},
);
}
/// 配置异常
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() => _formatExceptionDetails(
'ConfigurationException: $message',
{
'配置键': configKey,
'配置值': configValue,
'来源': source,
'详细信息': details,
},
);
}
/// 网络异常
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() => _formatExceptionDetails(
'NetworkException: $message',
{
'URL': url,
'方法': method,
'状态码': statusCode,
'超时': timeout != null ? '${timeout!.inSeconds}' : null,
'详细信息': details,
},
);
}
/// 缓存异常
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() => _formatExceptionDetails(
'CacheException: $message',
{
'缓存键': cacheKey,
'操作': operation,
'缓存类型': cacheType,
'详细信息': details,
},
);
}
/// 性能异常
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() => _formatExceptionDetails(
'PerformanceException: $message',
{
'操作': operation,
'耗时': duration != null ? '${duration!.inMilliseconds}ms' : null,
'阈值': threshold != null ? '${threshold!.inMilliseconds}ms' : null,
'详细信息': details,
},
);
}
/// 类型异常
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() => _formatExceptionDetails(
'TypeException: $message',
{
'属性名': propertyName,
'期望类型': expectedType,
'实际类型': actualType,
'': value,
'详细信息': details,
},
);
}
/// 异常处理器
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) {
appLogger.severe(
'🚨 异常: $exception',
exception,
StackTrace.current,
);
}
/// 记录异常到文件
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);
} on Exception catch (e, stackTrace) {
appLogger.severe('记录异常到文件失败', e, stackTrace);
}
}
/// 清理异常处理器
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});
}