mcpField
N
n8n-error-handling-official

n8n-error-handling-official

github.com/n8n-io开发5582.1k 次安装2 周前更新
代码仓库

关于 n8n-error-handling-official

为使用 n8n 的 Agent 提供工作流错误处理规范,涵盖 Webhook API 和无人值守流程。重点是结构化错误响应、节点级重试与工作流级错误捕获。

主要功能

  1. 01配置节点错误输出
  2. 02按原因映射 HTTP 状态码
  3. 03为网络节点设置重试
  4. 04配置工作流级错误流程
  5. 05使用 Set IIFE 校验输入

适用场景

  1. 01构建带错误响应的 Webhook API
  2. 02为定时或队列流程捕获故障
  3. 03区分调用方错误与上游故障

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/n8n-io/skills --skill n8n-error-handling-official

安装后在 Claude Code 中输入/n8n-error-handling-official确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
API_WORKFLOWS.md
ERROR_WORKFLOWS.md
NODE_ERROR_OUTPUTS.md
RESPONSE_SHAPES.md
references/examples/
validation-subworkflow-usage.ts
validation-subworkflow.ts

详细介绍

n8n 错误处理

n8n 节点的默认行为:发生错误 → 工作流停止 → 调用方得不到任何有用信息。对于无人值守的工作流(Webhook API、计划任务、队列工作进程)来说,这种默认行为并不合适。症状就是“集成突然停止工作”,却没有日志、消息或线索。

本技能介绍如何处理错误,让故障清晰可见、结构化且可恢复。理想情况下,还能以自动修复的方式处理故障。

不可妥协的要求

对于任何API 形态的工作流(Webhook 触发器搭配 Respond to Webhook):

  1. 每个可能失败的节点都要连接错误输出,并且两条路径最终都要到达 Respond to Webhook。 不要留下悬空的错误分支,否则调用方会遇到超时。“可能失败”指 HTTP、数据库、第三方 API、文件操作以及任何可能抛出错误的操作。
  2. 状态码要对应故障原因。 调用方的错误 → 4xx;你这边的错误 → 5xx。在错误路径上默认返回 200 会造成无声故障:调用方以为成功了,却处理了空数据。

对于任何无人值守的工作流(计划任务、cron、队列驱动、Agent 工具): 3. 设置工作流级错误工作流。 捕获节点级处理未能处理的错误:超时、节点之间的崩溃、未连接错误输出的节点发生的错误。通过 update_workflow setWorkflowSettings.errorWorkflow 设置(n8n 2.29.0+);目标工作流必须是已发布且包含激活状态的 Error Trigger 的工作流,否则更新会被拒绝。参见 references/ERROR_WORKFLOWS.md。

强烈建议的默认做法

  • 错误响应正文应采用结构化格式。 不要只返回“Internal Server Error”。请使用 { "error": "<short identifier>", "message": "<human-readable>" }。参见 references/RESPONSE_SHAPES.md。
  • 配置调用网络的节点的 retryOnFail。 瞬时 429 和上游短暂故障会在到达错误路径前得到处理。参见下文“针对瞬时故障的自愈”。

何时可以放宽错误处理要求

仅供内部使用的一次性工作流,只有你一个用户、你会检查每次运行,并且故障的代价只是“我发现后重新运行”。默认的 onError: 'stopWorkflow' 就可以。判断标准是:如果除了你以外,还有其他人会看到输出(下游系统、最终用户、值班人员),就必须遵守不可妥协的要求。

API 工作流结构

标准的 Webhook API 工作流:

Webhook trigger
  ├── (success path)  → Process → Respond to Webhook (200, body)
  └── (any node's error output)
                       → Respond to Webhook (5xx, structured error body)
                       → Optional: log to error tracker / logger / notify channel

如需了解如何将多个可能失败的节点连接到同一个错误响应节点,请参见 references/API_WORKFLOWS.md 中的完整操作指南。

架构验证器(Set IIFE)

对于任何需要验证输入的 Webhook API,应将基于 Set 的架构验证器模式嵌入端点,而不是为每个字段编写 IF/Switch 链。以下两个示例文件是权威参考:

  • references/examples/validation-subworkflow.ts:基础模式(Webhook → Set(含验证 IIFE)→ Respond,状态码由表达式驱动)。适合作为最简演示。
  • references/examples/validation-subworkflow-usage.ts:端点模式(Webhook → Set → If valid → 业务逻辑 → 200 成功响应 / 400 响应,使用标准 {error: "validation_error", message, details, request_schema} 正文)。将此模式嵌入端点,并用实际逻辑替换 NoOp 占位符。

使用此模式的 Agent 操作步骤:

  1. 将用法示例的结构嵌入新端点。 Webhook → Set(Validate Schema)→ If Params Valid → 业务逻辑 → success/400 Respond。不要另起炉灶。
  2. 根据你的架构编辑 IIFE。 为端点的输入结构更新 REQUIRED_SCHEMA 以及 Set 节点表达式中的逐字段检查。架构常量下面的模式是机械式的:存在性检查、类型检查、约束检查、将错误推入 errors[]。
  3. 不要更改输出结构。 valid、validationError、details、requiredSchema 是 Respond 节点使用的契约。重命名会破坏响应正文。

完整操作步骤、支持的约束模式、架构设计规则,以及 ={{ ... }} 包装时需要注意的问题,见 references/API_WORKFLOWS.md 中的“Schema validator (Set IIFE)”。

每个节点的错误设置(回顾)

每个可能失败的节点都需要进行两项更改(参见 references/NODE_ERROR_OUTPUTS.md):

  1. 在节点配置中设置 onError: 'continueErrorOutput'。
  2. 将 output(1) 连线至错误处理器。

两项都必须设置。只设置其中一项会导致错误被静默处理。

瞬时故障时的自我恢复

连接错误路径之前,请先为所有会发起网络调用的节点配置节点级重试(HTTP Request、Gmail/Slack/Discord 等通信节点、数据库、AI、第三方 API 节点)。这样可以消化瞬时的 429 错误和短暂的上游故障,因此错误输出只会在真正发生故障时触发,告警和 5xx 响应也能反映实际问题,而非噪声。

{
    retryOnFail: true,
    maxTries: 3,
    waitBetweenTries: 5000,    // ms; 5000 is the max and should be your default
}

适用于所有调用网络服务的节点,不仅限于 HTTP Request。引擎会对任何错误进行重试,不按状态码筛选,并将 maxTries 上限设为 5、waitBetweenTries 上限设为 5000ms(packages/core/src/execution-engine/workflow-execute.ts)。节点特定说明请参阅 n8n-node-configuration-official 的 HTTP_NODES.md 和 AI_NODES.md。

响应格式:根据原因映射状态码

返回 text/plain "Internal Server Error" 的 5xx 响应在技术上属于 5xx,但毫无用处。而且并非所有错误都是 5xx。应根据请求失败的原因匹配状态码。

常见错误: 将所有错误路径都接到一个返回 500 "internal_error" 的 Respond to Webhook。即使调用方发送了错误输入,在调用方看来所有失败也都一样。这会破坏监控:你无法区分真正的服务中断和调用方输入错误。

按原因映射的默认值:

原因状态码错误代码路径
缺少必填字段或类型错误400validation_error使用基于 Set 的架构验证器提前验证(基本模式见 references/examples/validation-subworkflow.ts,端点模板见 validation-subworkflow-usage.ts);对于简单情况,也可以使用内联 IF/Switch + 专用的 400 响应。不要经过错误输出。理想情况下,在响应中回显架构,以便调用方自行修正。
缺少认证或认证无效401unauthorized同上。提前检查,直接返回 401。
已通过认证,但无权访问403forbidden同上。
请求中存在资源 ID,但数据中不存在404not_found从查找结果分支,而不是从查找错误分支。
操作与当前状态冲突(重复、竞争)409conflict通过逻辑检测,而不是错误输出。
调用方超出速率限制429rate_limit_exceeded设置 Retry-After 标头。
节点抛出异常,但原因未知500internal_error错误输出路径。
第三方 API 出错502upstream_errorHTTP Request 节点的错误输出。
工作流目前无法处理请求(下游服务宕机、上游服务触发速率限制)503service_unavailable根据具体错误检测,并附带提示返回。
第三方 API 超时504upstream_timeout根据错误消息筛选错误输出。

两种不同的流程:

  • **验证失败(4xx)**在执行工作之前通过 IF/Switch 分支检查,而不是通过错误输出处理。针对不同格式使用专用的 Respond(缺少字段时返回 400、未认证时返回 401,等等)。
  • **执行失败(5xx)**来自错误输出(“我们尝试了,但出了问题”)。所有 5xx 共用一个错误响应节点即可。必要时,可检查失败的节点来区分响应正文中的 error 代码。

使用一个 Respond,通过表达式设置状态码。 如果错误路径的差异仅在状态码和消息文本(正文格式相同,标头和内容类型没有变化),就不要通过 Switch 分流到 N 个 Respond 节点。Respond to Webhook 节点的 Response Code 和正文栏位支持表达式。直接内联计算状态码,让一个 Respond 节点处理整个错误路径。

// Response Code on a single Respond to Webhook node:
{{ (() => {
    const msg = $json.error?.message || $json.message || ''
    if (msg.includes('INVALID_ID')) return 400
    if (/429|too many/i.test(msg)) return 429
    if (/openrouter|anthropic|llm/i.test(msg)) return 502
    return 500
})() }}

只有当响应在结构上存在差异时,Switch + N 个 Respond 节点才有必要:例如标头不同、正文格式不同、重定向或内容类型不同。格式相同、仅数字不同,就用一个由表达式驱动的 Respond。

完整约定(包括关联 ID、可重试与致命错误标志、验证详情和速率限制格式)请参阅 references/RESPONSE_SHAPES.md。

工作流级错误工作流

对于无人值守的工作流,请将实例的错误工作流(或单个工作流的覆盖设置)配置为指向一个工作流,该工作流需要:

  1. 捕获故障信息(工作流名称、执行 ID、错误、堆栈)。
  2. 通知相关人员(Slack、电子邮件、值班人员)。
  3. 可选地,将重试任务加入队列(使用退避策略)。

捕获逐节点处理无法处理的情况:超时、节点间崩溃、未接线节点中的错误。

请参阅 references/ERROR_WORKFLOWS.md。

参考文件

文件阅读时机
references/API_WORKFLOWS.md构建或审查 webhook 触发/响应 webhook 工作流时
references/ERROR_WORKFLOWS.md为生产工作流设置工作流级错误捕获时
references/RESPONSE_SHAPES.md定义 API 的响应体规范时
references/NODE_ERROR_OUTPUTS.md为单个可能失败的节点连接按节点配置的错误输出时

反模式

反模式问题修复方法
Webhook → 处理 → 响应,没有错误分支调用方收到超时或空的 500 响应将每个可能失败的节点的 output(1) 连接到 Respond to Webhook
两条路径共用一个 Respond to Webhook响应体无法告知调用方发生了什么使用两个 Respond 节点,每条路径各一个,并明确设置代码和响应体
错误路径返回 200,响应体为 { "error": ... }调用方的 HTTP 客户端会将其视为成功,因此不会触发错误处理错误路径始终返回 4xx/5xx
在 Code 节点中捕获错误,并将其作为数据返回下游会收到错误格式的数据,工作流仍会继续让它抛出错误,配置 onError: 'continueErrorOutput' 并连接错误路径
生产工作流没有工作流级错误工作流真正发生故障时无处处理设置错误工作流。参见 ERROR_WORKFLOWS.md
每次失败都返回通用的“Internal Server Error”无法区分调用方错误、上游错误或速率限制使用结构化错误代码。参见 RESPONSE_SHAPES.md
生产节点调用不稳定或受速率限制的 API,却未设置 retryOnFail每次短暂的 429 或上游抖动都会表现为 5xx,并触发无谓的告警在节点上设置 retryOnFail: true, maxTries: 3, waitBetweenTries: 5000。参见“短暂故障时的自愈”
除 200 外的所有情况都返回 500调用方无法区分自己的错误输入和服务中断,因此监控会因你的问题而触发告警根据原因映射状态码。调用方问题使用 4xx。
根据错误消息使用 Switch → 多个仅状态码不同的 Respond 节点5 个节点只为实现一个可由表达式驱动 Response Code 的 Respond在单个 Respond 中内联计算代码。参见上文“一个 Respond,由表达式驱动状态码”。

评论

支持 Markdown