Mastra 错误处理冒烟测试完整指南:从--test errors到 HTTP 状态码回归基线
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
导读
本文基于 Mastra 仓库中 .claude/skills/mastra-smoke-test/references/tests/errors.md 编写,系统讲解如何对 Mastra 应用执行"错误处理"专项冒烟测试(--test errors):既包括对 Studio UI 的 Agent、工具、导航与网络错误的人工验证,也包括对本地/云端 HTTP API 的 curl 级回归断言,并给出可直接对照的 HTTP 状态码与响应体基线。读完本文,你将掌握一套可复用的错误处理冒烟清单、一组即拷即用的 curl 探测命令,以及如何结合 Mastra 服务端源码(packages/server)理解这些错误码背后的实现机制,从而在发布前快速捕获"堆栈泄漏""错误码映射错误"等回归问题。
一、为什么需要独立的错误处理冒烟测试
Mastra 的核心交互面——Agent 对话、工具执行、工作流运行——都是对外的 HTTP API 与 Studio UI。任何一个环节的错误处理出现回归,都会直接表现为三种用户可感知的问题:堆栈跟踪泄漏、返回"Generic Error"式无信息错误、页面直接崩溃。错误冒烟测试的目标正是验证应用"优雅地处理错误并向用户展示友好的提示信息"。
在 .claude/skills/mastra-smoke-test/SKILL.md 的强制测试清单中,Errors 是第 9 项必测项,可通过--test errors单独触发,也可随完整冒烟流程一起执行。它在本地(--env local)、staging(--env staging)与生产(--env production)环境都适用。
二、前置准备:启动本地服务
运行错误测试前,先确认 dev server 已在 4111 端口就绪。SKILL.md 推荐的做法是:
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:4111 lsof -i :4111 || true若进程已退出,从生成的冒烟项目中重启并等待就绪:
cd "$SMOKE_DIR/smoke-project" pnpm run dev > "$SMOKE_DIR/logs/dev-server-browser.log" 2>&1 & for i in {1..60}; do code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:4111 || true) [ "$code" = 200 ] && break sleep 1 done服务就绪后,即可按下面的清单逐项测试。
三、UI 层错误处理测试清单
1. Agent 错误处理
导航到/agents,选择一个 Agent,然后故意输入三类有问题的内容:
- 空消息:直接发送空字符串;
- 超长消息:10000+ 字符;
- 纯特殊字符:
@#$%^&*()。
记录此时显示的错误信息,重点判断:显示的是堆栈跟踪,还是用户友好的提示。
2. 工具错误处理
导航到/tools,选择一个工具,用非法输入提交:
- 空必填字段:清空所有输入后提交;
- 错误数据类型:在数字字段中输入文本;
- 非法格式:不符合字段格式要求的值。
记录显示的校验信息内容。注意:工具层错误在服务端的行为与 Agent/工作流不同——工具无效输入返回200,且响应体带error: true与validationErrors(详见第五节基线表)。
3. 导航错误处理
- 导航到无效路由
/nonexistent-page,记录出现的页面或行为(404 页面、重定向或崩溃); - 导航到无效 Agent 详情页
/agents/fake-agent-id,记录错误处理行为。
4. 网络错误恢复
- 启动一个长时间运行的操作;
- 尽量短暂断开网络;
- 记录错误处理行为,注意是否出现重试或恢复选项。
5. 需要记录与汇报的观察项
| 检查项 | 需要记录的内容 |
|---|---|
| Agent 错误 | 错误消息文本、是否显示堆栈跟踪 |
| 工具错误 | 校验消息内容 |
| API 错误 | HTTP 状态码、错误消息内容 |
| 404 页面 | 页面行为与内容 |
| 网络错误 | 错误处理行为 |
四、错误消息质量评估标准
无论 UI 还是 API,良好的错误消息都应具备四个特征:
- 解释发生了什么(What went wrong);
- 建议如何修复(How to fix it);
- 不暴露内部细节(Not expose internal details);
- 非开发者也能读懂(Readable by non-developers)。
文档给出了正反例对比:
- 反面:
TypeError: Cannot read property 'x' of undefined - 正面:
Unable to process your request. Please try again.
常见问题速查
| 问题 | 原因 | 修复方向 |
|---|---|---|
| 显示堆栈跟踪 | 错误未被捕获 | 添加错误边界(Error Boundary) |
| 通用 "Error" | 缺少错误消息 | 改进错误处理逻辑 |
| 页面崩溃 | 未处理异常 | 检查错误边界 |
从源码看,Mastra Playground 前端确实采用了错误边界机制:packages/playground/src/components/layout.tsx 中ErrorBoundary包裹在路由内容外层,并通过resetKeys={[pathname]}在路由切换时清除错误状态;其实现位于 packages/playground-ui/src/ds/components/ErrorBoundary/ErrorBoundary.tsx,使用 React 的componentDidCatch捕获渲染期异常。这为"页面崩溃→检查错误边界"这条修复建议提供了直接的实现落点。
五、API 层错误测试:curl 探测命令
本地与云端的通用探测
以下 curl 命令本地与云端通用,云端(staging/production)需要额外携带Authorization: Bearer <api-key>请求头;api-key 从平台控制台获取,并将<server-url>替换为你的环境地址。
# 未知 Agent curl -sw "\nHTTP %{http_code}\n" -X POST \ http://localhost:4111/api/agents/nonexistent/generate \ -H "Content-Type: application/json" \ -d '{"messages":[{"role":"user","content":"hi"}]}' # 工作流缺少必填输入字段 curl -sw "\nHTTP %{http_code}\n" -X POST \ http://localhost:4111/api/workflows/<workflowId>/start-async \ -H "Content-Type: application/json" \ -d '{"inputData":{}}' # 工具缺少必填输入字段 curl -sw "\nHTTP %{http_code}\n" -X POST \ http://localhost:4111/api/tools/<toolId>/execute \ -H "Content-Type: application/json" \ -d '{"data":{}}' # 未知工具 curl -sw "\nHTTP %{http_code}\n" -X POST \ http://localhost:4111/api/tools/nonexistent/execute \ -H "Content-Type: application/json" \ -d '{"data":{}}'云端环境的补充场景
针对--env staging或--env production,文档还给出了三类典型异常输入:
# 无效 Agent curl -X POST <server-url>/api/agents/nonexistent-agent/generate \ -H "Authorization: Bearer <your-api-key>" \ -H "Content-Type: application/json" \ -d '{"messages":[{"role":"user","content":"test"}]}' # 无效 JSON(非法的请求体) curl -X POST <server-url>/api/agents/<agent-id>/generate \ -H "Authorization: Bearer <your-api-key>" \ -H "Content-Type: application/json" \ -d 'not valid json' # 缺少必填字段 curl -X POST <server-url>/api/agents/<agent-id>/generate \ -H "Authorization: Bearer <your-api-key>" \ -H "Content-Type: application/json" \ -d '{}'对以上每个请求,需要记录:返回的 HTTP 状态码、错误消息内容、响应体中是否出现堆栈跟踪。
线程记忆场景的专项测试
文档还特别要求测试一个"线程作用域(thread-scoped)的 Observational Memory Agent 且未携带 memory payload"的场景:
curl -sw "\nHTTP %{http_code}\n" -X POST \ http://localhost:4111/api/agents/<agentKey>/generate \ -H "Content-Type: application/json" \ -d '{"messages":[{"role":"user","content":"test"}]}'这里threadId的必填要求是有意设计的,但由此产生的500被视为潜在的 API/UX 错误映射问题;如果提供了memory.resource而未提供memory.thread,请求可能提前被 schema 以400拒绝。文档要求将两条路径分别记录。
六、HTTP 状态码与响应体基线(回归断言核心)
这是错误冒烟测试最关键的产出:以下基线是当前服务端实际返回的、用于断言对照的值,任何偏差都应标记为回归。
| 场景 | HTTP | 响应体形状 |
|---|---|---|
| 未知 Agent id | 404 | { error: "Agent with id <id> not found" }(或类似) |
| 未知工具 id | 404 | { error: "Tool not found" } |
| 未知工作流 id | 404 | { error: "Workflow not found" } |
| 工作流缺少必填输入 | 500 | { error: "Invalid input data: <field> expected ..." } |
| 工具缺少必填输入 | 200 | { error: true, validationErrors: { ... } } |
| 无效 JSON 请求体 | 400 | { error: "..." }(Hono body 解析失败) |
通过标准(Pass Criteria)
- 每条错误响应都包含可读的
error字段(工具场景为validationErrors); - 响应体中不泄漏堆栈跟踪;
- HTTP 状态码与上表一致(或属于已记录的偏差)。
需要特别关注的已知问题
文档明确要求以批判眼光看待当前基线,而非无条件接受:
- 工作流 schema 校验失败返回 500:客户端输入导致的校验失败通常应映射为 4xx,因此将"工作流缺少必填输入返回 500"分类为潜在的服务端/API 错误映射 bug,而非可接受的通过项;
- 工具无效输入返回 200:响应体虽带
error: true,但与工作流、Agent 的 HTTP 语义不一致,被文档标记为已知不一致(known inconsistency)。
七、源码佐证:基线背后的服务端实现
上述基线并非凭空假设,而是与packages/server中的实际实现一一对应。为理解这些行为,可以对照以下源码位置:
- 未知 Agent → 404:packages/server/src/server/handlers/agents.ts 中
throw new HTTPException(404, { message:Agent with id ${agentId} not found}),与基线{ error: "Agent with id <id> not found" }一致;packages/server/src/server/handlers/agent-versions.ts 也有同样的 404 语义; - 未知工具 → 404:packages/server/src/server/handlers/tools.ts 与同文件多处(L261、L325、L358)均为
throw new HTTPException(404, { message: 'Tool not found' }); - 未知工作流 → 404:packages/server/src/server/handlers/workflows.ts 起、贯穿该文件的十余处分支均抛出
HTTPException(404, { message: 'Workflow not found' }); - 统一错误出口:packages/server/src/server/handlers/error.ts 的
handleError被接入所有路由:对MODEL_NOT_ALLOWED模型权限错误映射为422,对WORKFLOW_RESUME_ALREADY_CLAIMED并发恢复冲突映射为409,对WORKFLOW_SCHEMA_VALIDATION_FAILED映射为400,其余则回退到ApiError自带的status || details.status || 500。
值得留意的是 error.ts 中的isZodError采用了结构化 duck-typing 判断(name === 'ZodError'且存在issues数组)而非instanceof ZodError,这是因为不同依赖可能解析到不同的 zod 实例(zod@3 与 zod@4),instanceof会失效并导致校验错误丢失字段路径信息。这种实现细节解释了为什么错误冒烟测试要求"记录每条响应的error字段内容"——校验错误是否携带字段级信息,本身就是可观测的回归信号。
八、浏览器自动化操作参考
文档同时给出了可在浏览器工具中复现的最小操作序列:
# Agent 错误测试 Navigate to: /agents Click: Select agent Type: "@#$%^&*()" Send: Message Verify: Error is user-friendly # 工具错误测试 Navigate to: /tools Click: Select tool Clear: All inputs Click: Submit Verify: Validation error shown # 404 测试 Navigate to: /this-page-does-not-exist Verify: 404 or redirect, not crash执行--test errors时,若 UI 交互无法从无障碍快照中暴露足够文本,文档建议检查document.body.innerText或截图留存可见证据(参见 SKILL.md 的浏览器冒烟说明),而不是只依赖 API 输出。
九、结果汇报模板
完成全部测试后,将结论写入$SMOKE_DIR/smoke-report.md,参考 SKILL.md 的汇报结构:
## Smoke Test Results **Environment**: local/staging/production **Project**: <name> | Test | Status | Notes | | ------ | ------ | ----- | | Setup | ✅/❌ | | | Errors | ✅/❌ | | **Issues Found**: (list any) **Warnings**: (list any deploy/runtime warnings) **Skipped Tests**: (list with reason)汇报时务必把第五节中"已知不一致"与"疑似 500 映射 bug"单独列出,并给出具体的请求命令、状态码与响应体,便于后续在 packages/server 侧定位修复。
十、小结
Mastra 的错误处理冒烟测试(--test errors)是一条覆盖 UI 与 API 双层的回归防线:UI 侧重点验证 Agent、工具、导航与网络四类场景的用户体验,API 侧则用 curl 固定住 404/400/500 等状态码与响应体基线。结合 errors.md 的通过标准与 packages/server 的源码实现,测试者既能快速发现"堆栈泄漏""页面崩溃"这类明显回归,也能识别出"工具返回 200 + error:true"这类语义不一致的隐藏问题——这正是发布前错误处理质量保障的最小且高效的实践。
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考