
@wrap_tool_call middleware could allow to catch exceptions and turn them into ToolException
快速结论:该问题发生在 LangChain agent 中通过 @wrap_tool_call 中间件捕获工具异常并抛出 ToolException 时,异常无法被 agent 循环捕获,导致执行中断。优先排查方向:检查 ToolNode 是否启用了 handle_tool_errors,或确认 create_agent 构造的 ToolNode 是否未配置错误处理器。
问题场景
用户在编写 LangChain agent 工具时,使用 @wrap_tool_call 中间件捕获常见异常(如 FileNotFoundError、NotADirectoryError、BadZipFile)并试图通过 raise ToolException(err) 将错误信息回传给 agent 处理。实际运行时,该异常无法被 agent 层捕获,导致 agent 异常崩溃。
报错原文
The ToolException error is raised outside of the tools "handler" function and not inside, so somehow it's not caught. When running this code with agent.stream for example, the agent will crash because it doesn't catch ToolException higher up.
原因分析
经维护者追踪确认,create_agent 构造的 ToolNode 默认未启用 handle_tool_errors。当 wrap_tool_call 中间件内抛出 ToolException 时,默认错误处理器仅会捕获 LangGraph 内部的 ToolInvocationError(它虽继承自 ToolException),但对用户直接抛出的 ToolException 不会特殊处理,因此异常会直接向上传播导致 agent 崩溃。这是 LangChain 工具错误管理在开发体验上的一个空缺——文档中对 ToolException 的处理仅针对 LangGraph 的 ToolNode 有描述,但未覆盖 @tool 装饰器场景。
环境排查
- LangChain 版本(建议 >= 0.3.x,但问题存在于所有使用
@wrap_tool_call的版本) - LangGraph 版本(确认
ToolNode的默认错误处理器行为) - 是否使用了
create_agent构造 agent - 是否在
ToolNode初始化时显式设置了handle_tool_errors=True
解决步骤
- 确认问题现象:编写一个使用
@wrap_tool_call的中间件,在try/except中捕获异常并raise ToolException,然后以agent.stream运行,观察 agent 是否崩溃。 - 临时替代方案(推荐优先尝试):在中间件中不抛出
ToolException,而是直接返回一个ToolMessage(status="error", content=str(err))。例如:from langchain_core.messages import ToolMessage @wrap_tool_call def HandleFileErrorsMiddleware(request, handler): try: return handler(request) except (FileNotFoundError, NotADirectoryError, BadZipFile) as err: return ToolMessage(status="error", content=str(err))此方法能将错误文本回传给 agent,且 agent 不会崩溃。
- 待官方修复(两种可能方案,社区已提交):
- 方案一(langchain 侧):让
create_agent在构造ToolNode时自动将wrap_tool_call链中抛出的ToolException转换为ToolMessage(status="error")。 - 方案二(langgraph 侧):扩展默认的
handle_tool_errors使其能捕获并处理所有ToolException(包括用户自定义子类),而非仅处理ToolInvocationError。
- 方案一(langchain 侧):让
- 检查当前状态:访问 PR #37195 查看你的修复是否已被合并,若已合并则按新版本 API 使用。
验证方法
执行以下场景测试:
- 中间件中
raise ToolException后,agent 应继续执行并输出错误信息,而非崩溃。 - 使用
agent.stream时,流式输出中应包含错误相关消息,而非异常堆栈。
若使用临时替代方案(返回 ToolMessage),验证 agent 能收到错误内容并据此重试或回应。



