fix: 修复ComfyUI队列API响应格式解析问题

- 修复WebSocket错误消息解析失败问题,支持更多错误字段格式
- 改进执行错误处理,收到错误时立即中断而不是等待超时
- 修复ComfyUI队列API响应格式不匹配问题,支持数组格式的队列数据
- 添加灵活的队列项解析逻辑,支持整数和字符串类型的prompt_id
- 在EventEmitter中添加错误存储功能,支持实时错误状态检查
- 更新所有相关的队列状态转换代码

解决的问题:
1. WebSocket消息解析错误:missing field 'message'
2. 执行错误后仍等待超时的问题
3. 队列API响应解析错误:invalid type integer/string expected
4. 批量处理中错误统计不准确的问题
This commit is contained in:
imeepos
2025-08-11 11:09:27 +08:00
parent b1e7191c10
commit 2075a731d2
9 changed files with 224 additions and 17 deletions

View File

@@ -167,8 +167,15 @@ impl WebSocketClient {
/// Handles incoming WebSocket messages
async fn handle_message(text: &str, event_emitter: &EventEmitter) -> Result<()> {
// 打印原始消息用于调试
log::debug!("Received WebSocket message: {}", text);
let message: WSMessage = serde_json::from_str(text)
.map_err(|e| ComfyUIError::new(format!("Failed to parse WebSocket message: {e}")))?;
.map_err(|e| {
log::error!("Failed to parse WebSocket message: {}", e);
log::error!("Raw message content: {}", text);
ComfyUIError::new(format!("Failed to parse WebSocket message: {e}"))
})?;
match message {
WSMessage::Progress { data } => {
@@ -195,12 +202,40 @@ impl WebSocketClient {
event_emitter.emit_executed(result).await;
}
WSMessage::ExecutionError { data } => {
// 构建错误消息,尝试多个可能的字段
let error_message = data.message
.or(data.error)
.or(data.exception_message)
.or_else(|| {
// 尝试从extra字段中提取错误信息
data.extra.get("exception_message")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
})
.or_else(|| {
data.extra.get("error")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
})
.unwrap_or_else(|| "Unknown execution error".to_string());
// 获取节点ID
let node_id = data.node_id
.or(data.node)
.or_else(|| {
data.extra.get("node")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
});
let error = ExecutionError {
node_id: data.node_id,
message: data.message,
node_id,
message: error_message,
details: data.details,
timestamp: Utc::now(),
};
log::error!("ComfyUI execution error: {}", error.message);
event_emitter.emit_error(error).await;
}
WSMessage::Unknown => {
@@ -215,6 +250,16 @@ impl WebSocketClient {
pub fn event_emitter(&self) -> &EventEmitter {
&self.event_emitter
}
/// Gets the last execution error and clears it
pub async fn get_last_error(&self) -> Option<ExecutionError> {
self.event_emitter.get_last_error().await
}
/// Clears the last error
pub async fn clear_last_error(&self) {
self.event_emitter.clear_last_error().await
}
}
impl Drop for WebSocketClient {