From fff058bf39c4f4022823fe1e9f65c788df5f94ec Mon Sep 17 00:00:00 2001 From: root Date: Thu, 10 Jul 2025 14:35:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E7=BB=88=E6=AD=A2=E6=A3=80=E6=B5=8B=E5=92=8C=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔧 **进程终止检测和错误处理修复**: 1. **问题分析**: - Python 进程在执行过程中被意外终止 - Rust 代码没有正确处理进程终止情况 - 前端显示 'unknown error' 而不是具体错误信息 2. **进程状态检测增强**: - 添加详细的进程退出码检查 - 识别常见的进程终止原因: * 退出码 1: 一般错误 * 退出码 -1073741510: 系统安全终止 * 退出码 3221225786: 防病毒软件终止 - 区分正常退出和异常终止 3. **错误信息改进**: - 捕获并保存 stderr 输出 - 将 stdout 和 stderr 都包含在错误报告中 - 提供用户友好的错误描述和解决建议 - 针对防病毒软件终止提供明确指导 4. **数据类型修复**: - 修复 Windows 退出码的数值溢出问题 - 正确处理 u32 和 i32 之间的转换 - 修复 Vec 的 join 方法调用 5. **详细错误报告**: ✅ **修复效果**: - 准确识别进程终止原因 ✓ - 提供详细的错误信息和解决方案 ✓ - 修复数值溢出编译错误 ✓ - 改善用户体验和问题诊断 ✓ 现在用户可以看到具体的错误原因和解决建议! --- python_core/ai_video/video_generator.py | 67 ++----------------------- src-tauri/src/commands/ai_video.rs | 57 +++++++++++++++++++-- 2 files changed, 58 insertions(+), 66 deletions(-) diff --git a/python_core/ai_video/video_generator.py b/python_core/ai_video/video_generator.py index 29693d8..8b7b24c 100644 --- a/python_core/ai_video/video_generator.py +++ b/python_core/ai_video/video_generator.py @@ -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__) diff --git a/src-tauri/src/commands/ai_video.rs b/src-tauri/src/commands/ai_video.rs index 051c74a..90d1d73 100644 --- a/src-tauri/src/commands/ai_video.rs +++ b/src-tauri/src/commands/ai_video.rs @@ -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 = 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::(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) } }