跳到主要内容

n8n 节点中的错误处理

正确处理错误,是构建稳定 n8n 节点的关键,能在发生问题时向用户提供清晰反馈。n8n 提供两个专门的错误类,用于处理节点实现中的不同故障:

NodeApiError ​

处理外部 API 调用和 HTTP 请求时,请使用 NodeApiError。此错误类专用于处理 API 响应错误,并增强了解析和展示以下 API 相关故障的能力:

  • HTTP 请求失败
  • 外部 API 错误
  • 身份验证或授权失败
  • 请求速率限制错误
  • 服务不可用错误

使用以下方式初始化新的 NodeApiError 实例:

new NodeApiError(node: INode, errorResponse: JsonObject, options?: NodeApiErrorOptions)

常见用法 ​

对于基本的 API 请求失败,捕获错误并将其包装为 NodeApiError:

try {
const response = await this.helpers.httpRequestWithAuthentication.call(
this,
credentialType,
options
);
return response;
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}

针对特定 HTTP 状态码提供自定义消息:

try {
const response = await this.helpers.httpRequestWithAuthentication.call(
this,
credentialType,
options
);
return response;
} catch (error) {
if (error.httpCode === "404") {
const resource = this.getNodeParameter("resource", 0);
const errorOptions = {
message: `${
resource.charAt(0).toUpperCase() + resource.slice(1)
} not found`,
description:
"The requested resource could not be found. Please check your input parameters.",
};
throw new NodeApiError(
this.getNode(),
error as JsonObject,
errorOptions
);
}

if (error.httpCode === "401") {
throw new NodeApiError(this.getNode(), error as JsonObject, {
message: "Authentication failed",
description: "Please check your credentials and try again.",
});
}

throw new NodeApiError(this.getNode(), error as JsonObject);
}

NodeOperationError ​

以下情况请使用 NodeOperationError:

  • 操作错误
  • 验证失败
  • 与外部 API 调用无关的配置问题
  • 输入验证错误
  • 缺少必填参数
  • 数据转换错误
  • 工作流逻辑错误

使用以下方式初始化新的 NodeOperationError 实例:

new NodeOperationError(node: INode, error: Error | string | JsonObject, options?: NodeOperationErrorOptions)

常见用法 ​

使用 NodeOperationError 验证用户输入:

const email = this.getNodeParameter("email", itemIndex);

if (email.indexOf("@") === -1) {
const description = `The email address '${email}' in the 'email' field isn't valid`;
throw new NodeOperationError(this.getNode(), "Invalid email address", {
description,
itemIndex, // for multiple items, this will link the error to the specific item
});
}

处理多个数据项时,请包含数据项索引,以提供更完整的错误上下文:

for (let i = 0; i < items.length; i++) {
try {
// Process item
const result = await processItem(items[i]);
returnData.push(result);
} catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: { error: error.message },
pairedItem: { item: i },
});
continue;
}

throw new NodeOperationError(this.getNode(), error as Error, {
description: error.description,
itemIndex: i,
});
}
}

声明操作失败的原因 ​

信息

功能可用范围

从 n8n 3.37 起可使用失败声明。

NodeApiError 和 NodeOperationError 都接受 failure 选项,用于说明操作失败的原因。当节点能根据响应确定具体问题时,例如配额耗尽或凭据失效,可以使用此选项。该声明作为普通数据存储在错误的 failure 属性中。节点只声明原因,不决定处理措施;所有根据声明采取的行为由 n8n 决定,例如轮询触发器在轮询失败后如何退避。

构造错误时传入声明:

throw new NodeApiError(this.getNode(), error as JsonObject, {
failure: { cause: 'rate-limited' },
});

失败原因 ​

cause 字段接受六个值之一。前三个值描述可自行恢复的故障,后三个值需要有人采取措施,操作才能成功。

cause含义
rate-limited服务正在限制请求速率。
quota-exhausted用量配额已耗尽,配额重置前操作都会失败。
temporarily-unavailable服务当前不可用或处于降级状态。
credential-invalid凭据已失效,用户需要重新连接。
configuration-invalid节点指向的对象已不存在,或已不再允许访问。
node-defect节点自身存在缺陷,与凭据和配置无关。

等待提示 ​

对于 rate-limited、quota-exhausted 和 temporarily-unavailable,可以添加可选提示,说明操作何时可能恢复。其他原因没有可等待的恢复条件,因此不接受这些提示。

字段含义
retryAfterMs服务要求的最短等待时间,单位为毫秒。
resetsAtEpochMs服务声明操作恢复的时间,使用 Unix 纪元毫秒数表示。

例如,对于已知重置时间的配额,可以声明其恢复时间:

throw new NodeApiError(this.getNode(), error as JsonObject, {
failure: { cause: 'quota-exhausted', resetsAtEpochMs: nextQuotaReset() },
});

对 API 错误进行分类 ​

只声明响应能够证明的原因。如果无法确定错误类别,请原样抛出错误;没有声明的错误仍然有效。

try {
return await this.helpers.httpRequestWithAuthentication.call(
this,
credentialType,
options
);
} catch (error) {
if (error.httpCode === "401") {
throw new NodeApiError(this.getNode(), error as JsonObject, {
failure: { cause: "credential-invalid" },
});
}

if (error.httpCode === "429") {
throw new NodeApiError(this.getNode(), error as JsonObject, {
failure: { cause: "rate-limited" },
});
}

throw new NodeApiError(this.getNode(), error as JsonObject);
}

相关资源 ​

本文为社区中文翻译。查看对应英文原文