
Improve exception handling while running workflow / chatflow
快速结论:该报错发生在 Dify 工作流或聊天流(Workflow/Chatflow)执行过程中,当异常在 BaseAppGenerator.generate() 返回之后、Worker 线程的 try/except 块开始之前被触发时,客户端(前端 UI)会陷入无限“运行中”状态,直到 300 秒空闲超时。优先排查是否缺少针对 generate() 返回后与 Worker 启动前这段间隙的异常捕获。
问题场景
用户在自托管(Self Hosted,Source 部署)的 Dify 环境中,运行 Workflow 或 Chatflow 应用时触发。核心问题点位于 BaseAppGenerator.generated 调用与 Worker 启动之间的执行间隙。
报错原文
Exception raised between BaseAppGenerator.generated() invocation and worker start, no SSE event sent to client. Frontend UI stuck in forever running state until 300-second idle timeout.
原因分析
这是一个已知的系统性问题,根本原因是:在 generate() 成功返回之后,但 Worker 线程尚未进入内部 try/except 块之前,如果发生异常,该异常不会被任何代码捕获,也就没有错误事件被发送到 SSE 队列,导致客户端持续等待。已有多个 PR 针对此问题进行了修复,核心模式相同:将关键操作移入 try 块,调用 queue_manager.publish_error() 发布错误,并确保 ERROR 事件在流式传输管道中被识别为终止信号。
环境排查
- 确认 Dify 版本:
main分支(Issue 中使用的版本) - 确认部署模式:Self Hosted (Source)
- 检查是否已应用以下修复 PR:
- PR #36970 — 为对话 Worker 中的
conversation和message添加空值保护,使用queue_manager.publish_error()替代静默崩溃 - PR #37244 — 对 advanced-chat 应用的对话/消息获取操作添加
try/except,捕获ConversationNotExistsError和MessageNotExistsError - PR #36973 — 将
StreamEvent.ERROR添加到默认终止事件集合,确保 SSE 流在传递错误后立即关闭 - PR #37100 — 在
WorkflowAppGenerator.generate()早期触发异常时,在错误载荷之后额外发布一个终止的workflow_finished事件 - PR #37236 — 确保
error事件在执行开始前收到致命错误的 Chatflow 中触发流终止
- PR #36970 — 为对话 Worker 中的
解决步骤
- 确认本地代码是否包含上述修复:检查代码仓库中
BaseAppGenerator及相关文件的变更记录。如果未包含,应合并或 cherry-pick 上述 PR 的改动。 - 排查具体触发场景(如已应用修复但问题仍存在):根据 Issue 提供的方法,收集触发时的完整异常信息和堆栈跟踪(stack trace),这有助于定位尚未被覆盖的代码间隙。
- 可优先尝试的临时解决方案:在
generate()返回后、启动 Worker 代码块前,手动添加额外的try/except块,确保任何异常都被捕获并通过queue_manager.publish_error()发送到 SSE 队列。
验证方法
复现原先导致 UI 卡死的场景,观察前端是否在异常发生后立即显示错误提示,而不是陷入无限“运行中”状态。如果修复生效,SSE 流应能正常发送错误事件并关闭连接,客户端不会等待直到 300 秒超时。



