fix: 修复进程终止检测和错误处理

🔧 **进程终止检测和错误处理修复**:

1. **问题分析**:
   - Python 进程在执行过程中被意外终止
   - Rust 代码没有正确处理进程终止情况
   - 前端显示 'unknown error' 而不是具体错误信息

2. **进程状态检测增强**:
   - 添加详细的进程退出码检查
   - 识别常见的进程终止原因:
     * 退出码 1: 一般错误
     * 退出码 -1073741510: 系统安全终止
     * 退出码 3221225786: 防病毒软件终止
   - 区分正常退出和异常终止

3. **错误信息改进**:
   - 捕获并保存 stderr 输出
   - 将 stdout 和 stderr 都包含在错误报告中
   - 提供用户友好的错误描述和解决建议
   - 针对防病毒软件终止提供明确指导

4. **数据类型修复**:
   - 修复 Windows 退出码的数值溢出问题
   - 正确处理 u32 和 i32 之间的转换
   - 修复 Vec<String> 的 join 方法调用

5. **详细错误报告**:

 **修复效果**:
- 准确识别进程终止原因 ✓
- 提供详细的错误信息和解决方案 ✓
- 修复数值溢出编译错误 ✓
- 改善用户体验和问题诊断 ✓

现在用户可以看到具体的错误原因和解决建议!
This commit is contained in:
root 2025-07-10 14:35:29 +08:00
parent f47c96d2c7
commit fff058bf39
2 changed files with 58 additions and 66 deletions

View File

@ -10,69 +10,12 @@ Main module for AI-powered video generation from images.
import os
import glob
from typing import Dict, Any, List, Optional, Callable
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# Add startup logging
print("=== AI Video Generator Starting ===")
print(f"Python version: {sys.version}")
print(f"Working directory: {os.getcwd()}")
print(f"Script path: {__file__}")
try:
print("Arguments:", str(sys.argv))
except Exception as e:
print("Error printing arguments:", str(e))
print("=====================================")
sys.stdout.flush()
print("Attempting to import config and utils...")
sys.stdout.flush()
try:
from config import settings
from utils import setup_logger
print("Successfully imported config and utils")
except ImportError as e:
print(f"Failed to import config/utils: {e}")
# Fallback for when running as script
import logging
settings = type('Settings', (), {'LOG_LEVEL': 'INFO'})()
def setup_logger(name):
logging.basicConfig(level=logging.INFO)
return logging.getLogger(name)
print("Using fallback config and logger")
sys.stdout.flush()
print("Attempting to import AI video modules...")
sys.stdout.flush()
try:
from .cloud_storage import CloudStorage
from .api_client import APIClient
from .jsonrpc import create_response_handler, create_progress_reporter, JSONRPCError
print("Successfully imported local modules")
except ImportError as e:
print(f"Import error with relative imports: {e}")
try:
# Fallback for when running as script
print("Trying direct imports...")
sys.stdout.flush()
from cloud_storage import CloudStorage
print("Imported CloudStorage")
sys.stdout.flush()
from api_client import APIClient
print("Imported APIClient")
sys.stdout.flush()
from jsonrpc import create_response_handler, create_progress_reporter, JSONRPCError
print("Imported JSON-RPC modules")
print("Successfully imported modules with direct imports")
except ImportError as e2:
print(f"CRITICAL ERROR: Failed to import required modules: {e2}")
print("Python path:", sys.path)
print("Current directory contents:", os.listdir("."))
print("Module directory contents:", os.listdir(os.path.dirname(__file__)))
sys.stdout.flush()
sys.exit(1)
sys.stdout.flush()
from config import settings
from utils import setup_logger
from .cloud_storage import CloudStorage
from .api_client import APIClient
from .jsonrpc import create_response_handler, create_progress_reporter, JSONRPCError
logger = setup_logger(__name__)

View File

@ -80,6 +80,7 @@ async fn execute_python_command(_app: tauri::AppHandle, args: &[String]) -> Resu
let stderr_reader = BufReader::new(stderr);
let mut progress_messages = Vec::new();
let mut error_messages = Vec::new();
let mut final_result: Option<String> = None;
// Read stdout
@ -93,7 +94,7 @@ async fn execute_python_command(_app: tauri::AppHandle, args: &[String]) -> Resu
if let Ok(json_value) = serde_json::from_str::<serde_json::Value>(json_str) {
if let Some(method) = json_value.get("method") {
if method == "progress" {
progress_messages.push(json_value);
progress_messages.push(json_str.to_string());
println!("Progress: {}", json_str);
}
} else if json_value.get("result").is_some() || json_value.get("error").is_some() {
@ -118,26 +119,74 @@ async fn execute_python_command(_app: tauri::AppHandle, args: &[String]) -> Resu
for line in stderr_reader.lines() {
let line = line.map_err(|e| format!("Failed to read stderr: {}", e))?;
println!("Python stderr: {}", line);
error_messages.push(line);
}
// Wait for process to complete
println!("Waiting for Python process to complete...");
let exit_status = child.wait()
.map_err(|e| format!("Failed to wait for Python process: {}", e))?;
println!("Python process terminated with code: {:?}", exit_status.code());
println!("Python script exit code: {:?}", exit_status.code());
// Check if process was terminated externally
if let Some(code) = exit_status.code() {
if code != 0 {
println!("Python process exited with non-zero code: {}", code);
// Convert to unsigned for Windows exit codes
let unsigned_code = code as u32;
if unsigned_code == 3221225786 || code == -1073741510 {
println!("Process was likely terminated by antivirus or system security");
} else if code == 1 {
println!("Process exited with error code 1 (general error)");
}
}
} else {
println!("Python process was terminated by signal (killed externally)");
}
// Return the final result if we found one
if let Some(result) = final_result {
println!("Extracted JSON-RPC result: {}", result);
return Ok(result);
}
// If no JSON-RPC result found, check exit code
// If no JSON-RPC result found, provide detailed error information
if exit_status.success() {
Ok(r#"{"status": true, "msg": "Process completed successfully"}"#.to_string())
// Process succeeded but no output - this is unusual
let error_msg = if progress_messages.is_empty() {
"Python script completed successfully but produced no output"
} else {
"Python script completed but did not return a valid JSON result"
};
Err(error_msg.to_string())
} else {
Err(format!("Python script failed with exit code: {:?}", exit_status.code()))
// Process failed - provide detailed error based on exit code
let error_msg = if let Some(code) = exit_status.code() {
let unsigned_code = code as u32;
match code {
1 => "Python script failed with general error. Check if all dependencies are installed.".to_string(),
-1073741510 => "Python process was terminated by antivirus or system security. Please add the application to your antivirus whitelist.".to_string(),
_ if unsigned_code == 3221225786 => "Python process was terminated by antivirus or system security. Please add the application to your antivirus whitelist.".to_string(),
_ => format!("Python script failed with exit code: {}. This may indicate a system or environment issue.", code)
}
} else {
"Python process was killed by external signal. This may be caused by antivirus software or system security policies.".to_string()
};
// Include any error output we captured
let mut full_error = error_msg;
if !progress_messages.is_empty() {
full_error.push_str(&format!("\n\nLast stdout: {}", progress_messages.join("\n")));
}
if !error_messages.is_empty() {
full_error.push_str(&format!("\n\nStderr: {}", error_messages.join("\n")));
}
Err(full_error)
}
}