fix: 修复 JSON-RPC 通信中的状态识别和结果解析问题

🔧 关键修复:

1. Python 脚本最终结果输出:
   - 在函数结束前发送 JSON-RPC 格式的最终结果
   - 成功时:rpc.success(result)
   - 失败时:rpc.error(JSONRPCError.GENERATION_FAILED, msg, details)
   - 确保最终结果是标准 JSON-RPC 2.0 格式

2. Rust 解析逻辑优化:
   - 区分进度通知和最终结果响应
   - 优先返回 JSON-RPC 结果/错误响应
   - 备用机制:检查直接 JSON 中的 status 字段
   - 避免返回进度消息作为最终结果

3. 前端 JSON-RPC 响应处理:
   - 检测 jsonrpc: '2.0' 格式
   - 提取 result 字段作为成功结果
   - 处理 error 字段并抛出相应错误
   - 保持向后兼容直接 JSON 格式

4. 错误处理链路完善:
   - Python 异常 → JSON-RPC 错误响应
   - Rust 解析 → 提取错误信息
   - 前端处理 → 显示具体错误原因
   - 端到端的错误传播机制

 修复效果:
- 正确识别成功/失败状态 ✓
- 返回最终结果而非进度消息 ✓
- 标准化的错误处理 ✓
- 完整的 JSON-RPC 2.0 支持 ✓

现在前端应该能正确显示视频生成的成功状态!
This commit is contained in:
root 2025-07-10 13:07:50 +08:00
parent e1327c695b
commit 66ec36b474
3 changed files with 31 additions and 6 deletions

View File

@ -206,6 +206,14 @@ class VideoGenerator:
result['error_details'] = error_details
logger.error(f"Video generation failed: {result['msg']}")
logger.error(f"Traceback: {error_details['traceback']}")
progress.error(result['msg'])
rpc.error(JSONRPCError.GENERATION_FAILED, "Video generation failed", error_details)
# Send final result via JSON-RPC
if result['status']:
rpc.success(result)
else:
rpc.error(JSONRPCError.GENERATION_FAILED, result.get('msg', 'Unknown error'), result)
return result

View File

@ -135,17 +135,20 @@ async fn execute_python_command(app: tauri::AppHandle, args: &[String]) -> Resul
progress_messages.push(json_value);
println!("Progress: {}", json_str);
}
} else if json_value.get("result").is_some() {
// This is a final result
} else if json_value.get("result").is_some() || json_value.get("error").is_some() {
// This is a final result or error response
final_result = Some(json_str.to_string());
println!("Final result: {}", json_str);
println!("Final JSON-RPC result: {}", json_str);
}
}
} else if line.trim().starts_with('{') && line.trim().ends_with('}') {
// Fallback: try to parse as direct JSON result
if let Ok(_) = serde_json::from_str::<serde_json::Value>(line.trim()) {
final_result = Some(line.trim().to_string());
println!("Direct JSON result: {}", line.trim());
if let Ok(json_value) = serde_json::from_str::<serde_json::Value>(line.trim()) {
// Check if this looks like a final result (has status field)
if json_value.get("status").is_some() {
final_result = Some(line.trim().to_string());
println!("Direct JSON result: {}", line.trim());
}
}
}
}

View File

@ -389,6 +389,20 @@ export class AIVideoService {
const parsedResult = JSON.parse(result as string)
console.log('Parsed result:', parsedResult)
// Handle JSON-RPC response format
if (parsedResult.jsonrpc === "2.0") {
if (parsedResult.result) {
// Success response
console.log('JSON-RPC success result:', parsedResult.result)
return parsedResult.result
} else if (parsedResult.error) {
// Error response
console.error('JSON-RPC error:', parsedResult.error)
throw new Error(parsedResult.error.message || 'JSON-RPC error')
}
}
// Fallback: direct result format
return parsedResult
} catch (error) {
console.error('Failed to generate AI video:', error)