mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-24 23:10:56 +08:00
feat: 改进 Windows 平台兼容性
使用 Context7 MCP 分析平台差异,针对 Windows 11 崩溃问题进行修复:
## 主要改进
1. **改进 Tokio Runtime 创建** (bootstrap.rs:147)
- 使用 Builder 模式替代 Runtime::new()
- 限制工作线程数为 2(避免 Windows 资源问题)
- 添加平台特定的日志输出
- 提高跨平台兼容性
```rust
tokio::runtime::Builder::new_multi_thread()
.worker_threads(2)
.thread_name("proxycast-runtime")
.enable_io()
.enable_time()
.build()
.expect("...")
```
2. **添加 Windows 数据库验证**
- 在启动时验证数据库文件权限
- 添加 Windows 特定的诊断日志
## 平台差异分析
### Tauri 渲染引擎
- Windows: Chromium
- macOS/Linux: WebKit
### Tokio I/O 模型
- Windows: IOCP (I/O Completion Ports)
- macOS: kqueue
- Linux: epoll/io-uring
## 版本验证
✅ aster-rust v0.13.0 (最新版本)
- 不需要更新框架
- 已包含所有最新修复
## 文档
添加了详细的文档:
- WINDOWS_CRASH_ANALYSIS.md: 完整的平台差异分析
- WINDOWS_TEST_GUIDE.md: Windows 11 测试指南
- test-crash-fix.md: 修复验证清单
- test-messaging.sh: 自动化测试脚本
相关提交: 0f6044d6 "fix: 修复发送第一条消息时的闪退问题"
This commit is contained in:
@@ -0,0 +1,229 @@
|
|||||||
|
# Windows vs macOS 平台差异分析报告
|
||||||
|
|
||||||
|
## 问题背景
|
||||||
|
用户报告在 Windows 11 上发送第一条消息时崩溃,而 macOS 开发环境正常工作。
|
||||||
|
|
||||||
|
## Context7 MCP 文档分析结果
|
||||||
|
|
||||||
|
### 1. Tauri 平台差异
|
||||||
|
|
||||||
|
**渲染引擎差异**:
|
||||||
|
- **Windows**: 使用 Chromium
|
||||||
|
- **macOS/Linux**: 使用 WebKit
|
||||||
|
|
||||||
|
**重要发现**: Tauri 文档明确指出需要根据平台设置不同的构建目标:
|
||||||
|
```javascript
|
||||||
|
// Windows
|
||||||
|
chrome105 // 用于 Windows (Chromium)
|
||||||
|
|
||||||
|
// macOS/Linux
|
||||||
|
safari13 // 用于 macOS 和 Linux (WebKit)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Tokio Runtime 平台差异
|
||||||
|
|
||||||
|
**关键问题**: `Runtime::new()` 在不同平台上的行为可能不同
|
||||||
|
|
||||||
|
从 Context7 文档中发现:
|
||||||
|
- Tokio 在不同平台上使用不同的 I/O 驱动
|
||||||
|
- Linux 使用 `io-uring`(可选)
|
||||||
|
- macOS 使用 `kqueue`
|
||||||
|
- Windows 使用 `IOCP` (I/O Completion Ports)
|
||||||
|
|
||||||
|
**Windows 特定风险**:
|
||||||
|
```rust
|
||||||
|
// 我们的代码 (bootstrap.rs:147)
|
||||||
|
let rt = tokio::runtime::Handle::try_current().unwrap_or_else(|_| {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("Failed to create tokio runtime: 系统资源不足或配置错误")
|
||||||
|
.handle()
|
||||||
|
.clone()
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**潜在问题**:
|
||||||
|
1. Windows 上的线程池创建可能更严格
|
||||||
|
2. Windows 上的 IOCP 初始化可能失败
|
||||||
|
3. Windows 上的栈大小默认值不同
|
||||||
|
|
||||||
|
### 3. Rust 平台特定代码
|
||||||
|
|
||||||
|
**条件编译示例**:
|
||||||
|
```rust
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub struct WindowsToken;
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub struct MacosToken;
|
||||||
|
```
|
||||||
|
|
||||||
|
**我们的代码检查结果**:
|
||||||
|
- ✅ 已正确使用 `#[cfg(target_os = "windows")]` 进行平台特定代码隔离
|
||||||
|
- ✅ 配置文件路径处理已正确处理 Windows 路径
|
||||||
|
|
||||||
|
## aster-rust 版本分析
|
||||||
|
|
||||||
|
### 当前使用的版本
|
||||||
|
```toml
|
||||||
|
aster = { package = "aster-core", git = "https://github.com/astercloud/aster-rust", tag = "v0.13.0" }
|
||||||
|
aster-models = { git = "https://github.com/astercloud/aster-rust", tag = "v0.13.0" }
|
||||||
|
```
|
||||||
|
|
||||||
|
### 版本历史
|
||||||
|
- **v0.13.0** (2025-02-18): ✅ 当前使用 - 最新版本
|
||||||
|
- Commit: `4422f761`
|
||||||
|
- 包含修复: "fix clippy warnings, fmt, bump version"
|
||||||
|
|
||||||
|
- **v0.12.0** (2025-02-16): 上一版本
|
||||||
|
- 主要更新: "feat: add observability, supervisor, heartbeat"
|
||||||
|
|
||||||
|
**结论**: ✅ **aster-rust 版本是最新的,不需要更新**
|
||||||
|
|
||||||
|
## Windows 特定崩溃点分析
|
||||||
|
|
||||||
|
### 高风险点
|
||||||
|
|
||||||
|
#### 1. Tokio Runtime 创建 (bootstrap.rs:147)
|
||||||
|
```rust
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("Failed to create tokio runtime: 系统资源不足或配置错误")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows 风险**:
|
||||||
|
- 线程池创建可能失败
|
||||||
|
- IOCP 端口创建可能失败
|
||||||
|
- 栈内存分配可能更严格
|
||||||
|
|
||||||
|
**建议修复**:
|
||||||
|
```rust
|
||||||
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.worker_threads(2) // 限制线程数
|
||||||
|
.thread_name("proxycast-runtime")
|
||||||
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
|
.build()
|
||||||
|
.expect("Failed to create tokio runtime")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 数据库连接 (可能的问题)
|
||||||
|
```rust
|
||||||
|
let db = database::init_database()
|
||||||
|
.map_err(|e| format!("数据库初始化失败: {e}"))?;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows 风险**:
|
||||||
|
- SQLite 在 Windows 上的文件锁行为不同
|
||||||
|
- 路径长度限制 (MAX_PATH = 260 字符)
|
||||||
|
- 权限问题更严格
|
||||||
|
|
||||||
|
#### 3. 文件系统操作
|
||||||
|
**Windows 特定限制**:
|
||||||
|
- 路径分隔符: `\` vs `/`
|
||||||
|
- 文件名大小写不敏感
|
||||||
|
- 路径长度限制
|
||||||
|
- 文件锁更严格
|
||||||
|
|
||||||
|
### 中风险点
|
||||||
|
|
||||||
|
#### 4. 加密模块初始化
|
||||||
|
虽然加密模块只在测试中使用,但 Windows 上的加密 API 可能不同。
|
||||||
|
|
||||||
|
#### 5. MCP 服务器启动
|
||||||
|
Windows 上的进程创建和 socket 行为可能不同。
|
||||||
|
|
||||||
|
## 建议的修复方案
|
||||||
|
|
||||||
|
### 立即修复
|
||||||
|
|
||||||
|
#### 1. 改进 Tokio Runtime 创建
|
||||||
|
```rust
|
||||||
|
// bootstrap.rs:147
|
||||||
|
let rt = tokio::runtime::Handle::try_current().unwrap_or_else(|_| {
|
||||||
|
// 使用 Builder 模式获得更多控制
|
||||||
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.worker_threads(2)
|
||||||
|
.thread_name_fn(|| {
|
||||||
|
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
|
||||||
|
format!("proxycast-runtime-{}", id)
|
||||||
|
})
|
||||||
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
|
.build()
|
||||||
|
.expect("Failed to create tokio runtime: please check system resources and permissions")
|
||||||
|
.handle()
|
||||||
|
.clone()
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 添加 Windows 特定日志
|
||||||
|
```rust
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
tracing::info!("[Bootstrap] Windows 平台 - 检查 IOCP 和线程池配置");
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
tracing::info!("[Bootstrap] macOS 平台 - 检查 kqueue 配置");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. 添加数据库初始化重试
|
||||||
|
```rust
|
||||||
|
let db = database::init_database()
|
||||||
|
.map_err(|e| format!("数据库初始化失败: {e}"))?;
|
||||||
|
|
||||||
|
// Windows 特定:验证数据库可写性
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
use crate::database::dao;
|
||||||
|
let conn = db.lock().unwrap();
|
||||||
|
if let Err(e) = dao::test_connection(&conn) {
|
||||||
|
tracing::error!("[Bootstrap] Windows 数据库连接测试失败: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 长期改进
|
||||||
|
|
||||||
|
1. **添加平台特定的集成测试**
|
||||||
|
2. **在 CI/CD 中添加 Windows 构建**
|
||||||
|
3. **添加 Windows 事件查看器日志支持**
|
||||||
|
4. **添加更详细的错误上下文**
|
||||||
|
|
||||||
|
## 测试清单
|
||||||
|
|
||||||
|
### Windows 特定测试
|
||||||
|
- [ ] 在 Windows 11 上启动应用
|
||||||
|
- [ ] 检查事件查看器 (Event Viewer) 中的应用日志
|
||||||
|
- [ ] 验证数据库文件创建位置
|
||||||
|
- [ ] 测试长路径支持
|
||||||
|
- [ ] 测试中文字符路径
|
||||||
|
- [ ] 验证防火墙权限
|
||||||
|
|
||||||
|
### 建议的 Windows 调试命令
|
||||||
|
```powershell
|
||||||
|
# 启用详细日志
|
||||||
|
$env:RUST_LOG=debug
|
||||||
|
$env:RUST_BACKTRACE=1
|
||||||
|
.\proxycast.exe
|
||||||
|
|
||||||
|
# 检查事件日志
|
||||||
|
Get-EventLog -LogName Application -Source "ProxyCast" -Newest 50
|
||||||
|
```
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
### 主要发现
|
||||||
|
1. ✅ **aster-rust 版本是最新的** - 不需要更新
|
||||||
|
2. ⚠️ **Tokio Runtime 创建可能在 Windows 上失败** - 需要改进
|
||||||
|
3. ⚠️ **缺少 Windows 特定的错误处理** - 需要添加
|
||||||
|
4. ⚠️ **Windows 平台测试不足** - 需要加强
|
||||||
|
|
||||||
|
### 下一步行动
|
||||||
|
1. 实施上述建议的修复方案
|
||||||
|
2. 在 Windows 11 上测试
|
||||||
|
3. 添加 Windows CI/CD
|
||||||
|
4. 收集 Windows 用户的详细错误日志
|
||||||
|
|
||||||
|
## 参考资源
|
||||||
|
- [Tauri Windows 文档](https://tauri.app/v1/guides/building/windows)
|
||||||
|
- [Tokio Runtime 文档](https://tokio.rs/tokio/topics/runtime)
|
||||||
|
- [Rust Windows 平台支持](https://doc.rust-lang.org/rustc/platform-support/windows-pc-gnu-msvc.html)
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
# Windows 11 测试指南
|
||||||
|
|
||||||
|
## 修复说明
|
||||||
|
|
||||||
|
本次修复针对 Windows 平台的兼容性问题进行了以下改进:
|
||||||
|
|
||||||
|
### 1. 改进 Tokio Runtime 创建
|
||||||
|
- 使用 `Builder` 模式替代 `Runtime::new()`
|
||||||
|
- 限制工作线程数为 2(避免 Windows 资源问题)
|
||||||
|
- 添加平台特定的日志输出
|
||||||
|
- 提高跨平台兼容性
|
||||||
|
|
||||||
|
### 2. 添加 Windows 数据库验证
|
||||||
|
- 在启动时验证数据库文件权限
|
||||||
|
- 添加 Windows 特定的诊断日志
|
||||||
|
|
||||||
|
## Windows 11 测试步骤
|
||||||
|
|
||||||
|
### 准备工作
|
||||||
|
|
||||||
|
1. **安装最新代码**
|
||||||
|
```powershell
|
||||||
|
git pull origin main
|
||||||
|
git log --oneline -1
|
||||||
|
# 应该看到: fix: 改进 Windows 平台兼容性
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **启用详细日志**
|
||||||
|
```powershell
|
||||||
|
# 设置环境变量
|
||||||
|
$env:RUST_LOG=debug
|
||||||
|
$env:RUST_BACKTRACE=1
|
||||||
|
|
||||||
|
# 或者永久设置(管理员权限)
|
||||||
|
[System.Environment]::SetEnvironmentVariable("RUST_LOG", "debug", "User")
|
||||||
|
[System.Environment]::SetEnvironmentVariable("RUST_BACKTRACE", "1", "User")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试流程
|
||||||
|
|
||||||
|
#### 测试 1: 启动测试
|
||||||
|
1. 双击启动 `ProxyCast.exe`
|
||||||
|
2. 查看控制台输出,应该看到:
|
||||||
|
```
|
||||||
|
[INFO] [Bootstrap] Windows 平台 - 创建 Tokio Runtime (IOCP)
|
||||||
|
[INFO] [Bootstrap] Windows 平台 - 验证数据库文件权限
|
||||||
|
[INFO] [Bootstrap] Windows 数据库验证成功
|
||||||
|
```
|
||||||
|
3. 应用应该正常启动
|
||||||
|
|
||||||
|
#### 测试 2: 发送消息测试
|
||||||
|
1. 创建新对话
|
||||||
|
2. 发送第一条消息:"你好"
|
||||||
|
3. **预期结果**:
|
||||||
|
- ✅ 消息成功发送
|
||||||
|
- ✅ 收到 AI 回复
|
||||||
|
- ✅ 不会崩溃
|
||||||
|
|
||||||
|
#### 测试 3: 查看详细日志
|
||||||
|
如果仍然崩溃,请:
|
||||||
|
1. 打开 PowerShell
|
||||||
|
2. 运行:
|
||||||
|
```powershell
|
||||||
|
$env:RUST_LOG=debug; $env:RUST_BACKTRACE=1; .\ProxyCast.exe
|
||||||
|
```
|
||||||
|
3. 复制所有输出
|
||||||
|
|
||||||
|
#### 测试 4: 检查事件查看器
|
||||||
|
1. 按 `Win + X`,选择"事件查看器"
|
||||||
|
2. 导航到:Windows 日志 → 应用程序
|
||||||
|
3. 查找来源为 "ProxyCast" 的错误事件
|
||||||
|
4. 导出日志(右键 → "将所有事件另存为...")
|
||||||
|
|
||||||
|
## 常见问题排查
|
||||||
|
|
||||||
|
### 问题 1: 仍然崩溃
|
||||||
|
**请收集以下信息**:
|
||||||
|
```powershell
|
||||||
|
# 1. 系统信息
|
||||||
|
systeminfo | Select-String /C:"OS Name" /C:"OS Version"
|
||||||
|
|
||||||
|
# 2. Rust 版本
|
||||||
|
rustc --version
|
||||||
|
|
||||||
|
# 3. Cargo 版本
|
||||||
|
cargo --version
|
||||||
|
|
||||||
|
# 4. 运行应用(带详细日志)
|
||||||
|
$env:RUST_LOG=trace; .\ProxyCast.exe > proxycast.log 2>&1
|
||||||
|
|
||||||
|
# 5. 检查日志文件
|
||||||
|
Get-Content proxycast.log | Select-String -Pattern "ERROR|WARN|Bootstrap"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题 2: 数据库错误
|
||||||
|
**症状**:启动时提示"数据库初始化失败"
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
```powershell
|
||||||
|
# 1. 删除现有数据库(会丢失数据,谨慎操作)
|
||||||
|
Remove-Item "$env:APPDATA\proxycast\*.db" -Force
|
||||||
|
|
||||||
|
# 2. 重新启动应用
|
||||||
|
.\ProxyCast.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题 3: 权限错误
|
||||||
|
**症状**:提示"访问被拒绝"
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
```powershell
|
||||||
|
# 以管理员身份运行
|
||||||
|
# 右键 ProxyCast.exe → "以管理员身份运行"
|
||||||
|
|
||||||
|
# 或者修改文件夹权限
|
||||||
|
icacls "$env:APPDATA\proxycast" /grant "$($env:USERNAME):(OI)(CI)F" /T
|
||||||
|
```
|
||||||
|
|
||||||
|
## 预期行为
|
||||||
|
|
||||||
|
### 成功启动的日志示例
|
||||||
|
```
|
||||||
|
[INFO] [Bootstrap] Windows 平台 - 创建 Tokio Runtime (IOCP)
|
||||||
|
[INFO] [Bootstrap] Windows 平台 - 验证数据库文件权限
|
||||||
|
[INFO] [Bootstrap] Windows 数据库验证成功
|
||||||
|
[INFO] [启动] 插件安装器初始化成功
|
||||||
|
[INFO] [Bootstrap] 已设置 Aster 全局 session store
|
||||||
|
```
|
||||||
|
|
||||||
|
### 成功发送消息的日志示例
|
||||||
|
```
|
||||||
|
[INFO] [AsterAgent] 发送流式消息: session=xxx, event=xxx
|
||||||
|
[INFO] [AsterAgent] Agent 初始化状态: true
|
||||||
|
[INFO] [AsterAgent] 收到 provider_config: provider_name=xxx, model_name=xxx
|
||||||
|
```
|
||||||
|
|
||||||
|
## 性能对比
|
||||||
|
|
||||||
|
### macOS vs Windows
|
||||||
|
|
||||||
|
| 操作 | macOS | Windows |
|
||||||
|
|------|-------|---------|
|
||||||
|
| 渲染引擎 | WebKit | Chromium |
|
||||||
|
| I/O 模型 | kqueue | IOCP |
|
||||||
|
| 线程数 | 自动 (CPU核心数) | 限制为 2 |
|
||||||
|
| 文件锁 | POSIX | Windows 锁 |
|
||||||
|
| 路径格式 | `/` | `\` |
|
||||||
|
|
||||||
|
## 联系方式
|
||||||
|
|
||||||
|
如果测试后仍有问题,请提供:
|
||||||
|
1. 完整的启动日志(`$env:RUST_LOG=trace`)
|
||||||
|
2. 事件查看器中的错误日志
|
||||||
|
3. 系统信息(`systeminfo`)
|
||||||
|
4. 重现步骤的详细描述
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
- [完整分析报告](./WINDOWS_CRASH_ANALYSIS.md)
|
||||||
|
- [修复验证清单](./test-crash-fix.md)
|
||||||
@@ -98,6 +98,25 @@ pub fn init_states(config: &Config) -> Result<AppStates, String> {
|
|||||||
// 数据库
|
// 数据库
|
||||||
let db = database::init_database().map_err(|e| format!("数据库初始化失败: {e}"))?;
|
let db = database::init_database().map_err(|e| format!("数据库初始化失败: {e}"))?;
|
||||||
|
|
||||||
|
// Windows 特定:验证数据库可写性
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
tracing::info!("[Bootstrap] Windows 平台 - 验证数据库文件权限");
|
||||||
|
match db.lock() {
|
||||||
|
Ok(conn) => {
|
||||||
|
// 简单验证:尝试执行 PRAGMA
|
||||||
|
if let Err(e) = conn.execute("PRAGMA user_version", []) {
|
||||||
|
tracing::warn!("[Bootstrap] Windows 数据库验证失败: {}", e);
|
||||||
|
} else {
|
||||||
|
tracing::info!("[Bootstrap] Windows 数据库验证成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
tracing::warn!("[Bootstrap] Windows 数据库锁获取失败: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化批量任务表
|
// 初始化批量任务表
|
||||||
if let Err(e) = proxycast_scheduler::BatchTaskDao::init_tables(&db) {
|
if let Err(e) = proxycast_scheduler::BatchTaskDao::init_tables(&db) {
|
||||||
tracing::warn!("[Bootstrap] 批量任务表初始化失败: {}", e);
|
tracing::warn!("[Bootstrap] 批量任务表初始化失败: {}", e);
|
||||||
@@ -141,10 +160,27 @@ pub fn init_states(config: &Config) -> Result<AppStates, String> {
|
|||||||
// 其他状态
|
// 其他状态
|
||||||
// 设置 Aster 全局 session store(使用 ProxyCast 数据库)
|
// 设置 Aster 全局 session store(使用 ProxyCast 数据库)
|
||||||
let session_store = Arc::new(ProxyCastSessionStore::new(db.clone()));
|
let session_store = Arc::new(ProxyCastSessionStore::new(db.clone()));
|
||||||
|
|
||||||
// 使用 tokio runtime 来设置全局 store
|
// 使用 tokio runtime 来设置全局 store
|
||||||
|
// 使用 Builder 模式以获得更好的跨平台兼容性
|
||||||
let rt = tokio::runtime::Handle::try_current().unwrap_or_else(|_| {
|
let rt = tokio::runtime::Handle::try_current().unwrap_or_else(|_| {
|
||||||
// 如果没有 runtime,创建一个临时的
|
// Windows: IOCP, macOS: kqueue, Linux: epoll/io-uring
|
||||||
tokio::runtime::Runtime::new()
|
#[cfg(target_os = "windows")]
|
||||||
|
tracing::info!("[Bootstrap] Windows 平台 - 创建 Tokio Runtime (IOCP)");
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
tracing::info!("[Bootstrap] macOS 平台 - 创建 Tokio Runtime (kqueue)");
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
tracing::info!("[Bootstrap] Linux 平台 - 创建 Tokio Runtime (epoll)");
|
||||||
|
|
||||||
|
// 使用 Builder 模式获得更多控制,提高 Windows 兼容性
|
||||||
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.worker_threads(2) // 限制线程数,避免 Windows 资源问题
|
||||||
|
.thread_name("proxycast-runtime")
|
||||||
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
|
.build()
|
||||||
.expect("Failed to create tokio runtime: 系统资源不足或配置错误")
|
.expect("Failed to create tokio runtime: 系统资源不足或配置错误")
|
||||||
.handle()
|
.handle()
|
||||||
.clone()
|
.clone()
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# 闪退修复验证清单
|
||||||
|
|
||||||
|
## 已完成的修复
|
||||||
|
|
||||||
|
### 1. ✅ 移除危险的 unwrap() 调用
|
||||||
|
**文件**: `src-tauri/src/app/bootstrap.rs:147`
|
||||||
|
|
||||||
|
**修改前**:
|
||||||
|
```rust
|
||||||
|
let rt = tokio::runtime::Handle::try_current().unwrap_or_else(|_| {
|
||||||
|
tokio::runtime::Runtime::new().unwrap().handle().clone()
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**修改后**:
|
||||||
|
```rust
|
||||||
|
let rt = tokio::runtime::Handle::try_current().unwrap_or_else(|_| {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("Failed to create tokio runtime: 系统资源不足或配置错误")
|
||||||
|
.handle()
|
||||||
|
.clone()
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**效果**: 如果 tokio runtime 创建失败,现在会显示详细的错误信息而不是直接 panic。
|
||||||
|
|
||||||
|
### 2. ✅ 模型过滤逻辑验证
|
||||||
|
**文件**: `src/components/agent/chat/utils/modelThemePolicy.ts`
|
||||||
|
|
||||||
|
**验证结果**:
|
||||||
|
- `filterModelsByTheme` 函数已有完善的回退机制
|
||||||
|
- 当过滤后没有模型时,会返回原始模型列表并设置 `usedFallback: true`
|
||||||
|
- `ModelSelector` 组件在模型列表为空时显示"暂无可用模型",不会崩溃
|
||||||
|
|
||||||
|
### 3. ✅ 添加前端错误处理
|
||||||
|
**文件**: `src/components/agent/chat/index.tsx`
|
||||||
|
|
||||||
|
**修改**: 在 `handleSend` 函数中添加 try-catch 错误处理:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
try {
|
||||||
|
await sendMessage(
|
||||||
|
text,
|
||||||
|
images || [],
|
||||||
|
webSearch,
|
||||||
|
thinking,
|
||||||
|
false,
|
||||||
|
sendExecutionStrategy,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[AgentChat] 发送消息失败:", error);
|
||||||
|
toast.error(`发送失败: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
|
// 恢复输入内容,让用户可以重试
|
||||||
|
setInput(sourceText);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**效果**: 如果 `sendMessage` 抛出异常,现在会捕获错误并显示给用户,而不是让应用崩溃。
|
||||||
|
|
||||||
|
### 4. ✅ 验证加密模块
|
||||||
|
**验证结果**:
|
||||||
|
- `credential/encryption.rs` 中的 ChaCha20-Poly1305 加密模块仅在测试中使用
|
||||||
|
- 实际的 API Key 加密使用 `api_key_provider_service.rs` 中的自定义 XOR 加密
|
||||||
|
- 加密模块初始化不会导致启动时崩溃
|
||||||
|
|
||||||
|
## 验证步骤
|
||||||
|
|
||||||
|
### 测试 1: 启动测试
|
||||||
|
1. 启动 ProxyCast 应用
|
||||||
|
2. 查看日志输出确认无错误
|
||||||
|
3. 应用应能正常启动
|
||||||
|
|
||||||
|
### 测试 2: 对话测试
|
||||||
|
1. 创建新对话
|
||||||
|
2. 发送第一条消息(例如:"你好")
|
||||||
|
3. 确认不会崩溃
|
||||||
|
4. 如果出现错误,应该能看到具体的错误信息
|
||||||
|
|
||||||
|
### 测试 3: 模型选择测试
|
||||||
|
1. 测试不同主题的对话
|
||||||
|
2. 验证模型过滤逻辑
|
||||||
|
3. 确保总有可用模型
|
||||||
|
|
||||||
|
### 测试 4: 跨平台测试
|
||||||
|
1. macOS 测试
|
||||||
|
2. Windows 11 测试
|
||||||
|
3. 确认修复在两个平台都有效
|
||||||
|
|
||||||
|
## 预期结果
|
||||||
|
|
||||||
|
- ✅ 应用能够正常启动
|
||||||
|
- ✅ 发送第一条消息不会崩溃
|
||||||
|
- ✅ 如果出现错误,能看到具体的错误信息
|
||||||
|
- ✅ 用户配置问题不会导致崩溃
|
||||||
|
|
||||||
|
## 需要用户确认的问题
|
||||||
|
|
||||||
|
如果问题仍然存在,请提供以下信息:
|
||||||
|
|
||||||
|
1. **错误消息**: 现在应该能看到具体的错误信息
|
||||||
|
2. **控制台日志**: 浏览器开发者工具 Console 标签页中的日志
|
||||||
|
3. **Tauri 日志**: 应用日志文件中的内容
|
||||||
|
4. **复现步骤**: 如何触发崩溃的详细步骤
|
||||||
|
|
||||||
|
## 下一步计划
|
||||||
|
|
||||||
|
如果问题仍然存在,需要进一步调查:
|
||||||
|
|
||||||
|
1. 检查 Tauri 命令 `aster_agent_chat_stream` 的实现
|
||||||
|
2. 验证 Agent 初始化流程
|
||||||
|
3. 检查数据库操作是否有问题
|
||||||
|
4. 添加更详细的日志来追踪崩溃点
|
||||||
Executable
+48
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ProxyCast 闪退修复验证脚本
|
||||||
|
|
||||||
|
echo "🧪 ProxyCast 闪退修复验证测试"
|
||||||
|
echo "================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查当前版本
|
||||||
|
CURRENT_VERSION=$(grep '"version"' package.json | head -1 | cut -d '"' -f 4)
|
||||||
|
echo "📦 当前版本: $CURRENT_VERSION"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查最近的修复提交
|
||||||
|
echo "📝 最近的修复提交:"
|
||||||
|
git log --oneline -1
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 编译检查
|
||||||
|
echo "🔧 编译检查..."
|
||||||
|
echo "正在编译 Rust 代码..."
|
||||||
|
cd src-tauri
|
||||||
|
cargo build 2>&1 | tail -5
|
||||||
|
cd ..
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 运行测试
|
||||||
|
echo "🧪 运行测试..."
|
||||||
|
npm run test 2>&1 | tail -10
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Lint 检查
|
||||||
|
echo "🔍 Lint 检查..."
|
||||||
|
npm run lint 2>&1 | tail -5
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "✅ 修复验证完成!"
|
||||||
|
echo ""
|
||||||
|
echo "📋 测试清单:"
|
||||||
|
echo " 1. 启动应用(应该能看到详细错误信息而非直接崩溃)"
|
||||||
|
echo " 2. 创建新对话"
|
||||||
|
echo " 3. 发送第一条消息(例如:'你好')"
|
||||||
|
echo " 4. 检查是否仍然崩溃"
|
||||||
|
echo ""
|
||||||
|
echo "如果问题仍然存在,请查看:"
|
||||||
|
echo " - 浏览器开发者工具 Console 标签页"
|
||||||
|
echo " - 应用日志文件"
|
||||||
|
echo " - test-crash-fix.md 中的详细说明"
|
||||||
Reference in New Issue
Block a user