错误处理

虽然在一切正常时很容易创建正确运行的流程,但考虑可能出错的情况也很重要。

例如,如果流程与外部数据库或API交互,如果它停止响应请求会发生什么?或者如果MQTT节点失去与代理的连接呢?

任何应用程序中的错误处理对于确保正确处理这些类型的事件至关重要。如何处理错误将取决于应用程序的要求。您可能希望重试失败的操作,或触发单独的警报,或者错误可能是一个完全预期事件,只是应用程序逻辑的另一部分。

Node-RED提供了两种节点报告错误的方式。它可以只向日志写入消息,也可以向运行时通知错误并触发流程。

如果错误只写入日志,您将在调试侧边栏和日志输出中看到消息,但您将无法创建流程来处理它。这些是不可捕获的错误

如果它正确通知运行时,那么它是一个可捕获的错误,可以用于触发错误处理流程。

还有第三种错误可能导致Node-RED运行时关闭。这些uncaughtException错误无法在流程中处理,并且是由节点中的错误引起的。

本指南更详细地描述了这些错误类型,并展示了如何处理它们。它还探讨了如何使用节点的状态事件来创建处理意外事件的流程。

记录错误

当节点记录错误时,它将出现在调试侧边栏中。

Error message in the Debug sidebar

调试侧边栏中的错误消息

这显示了错误消息、错误的日期/时间以及记录错误的节点。与其他调试消息一样,将鼠标悬停在其上会高亮显示工作区中的节点。如果它不在当前视图中,则单击顶部角落的节点名称将在工作区中显示它。

可捕获的错误

如果节点通知运行时发生错误,则可以使用 Catch 节点创建流程来处理它。

Catch node

Catch 节点

如果错误被 Catch 节点捕获,它将不会记录到调试侧边栏。

由 Catch 发送的消息将是报告错误的节点提供的消息。此消息将设置一个error属性,提供有关错误的信息

{
    "topic": ...,
    "payload": ...,
    "error": {
        "message": "An error",
        "source": {
            "id": "2e25823d.fa3f7e",
            "type": "function",
            "name": "My Function",
            "count": 1
        }
    }
}

msg.error的属性是

  • msg.error:
    • message - 错误消息
    • source - 有关记录错误的节点的信息
      • id - 源节点ID
      • type - 源节点的类型
      • name - 源节点的名称(如果已设置)
      • count - 消息被节点抛出多少次。此属性由运行时用于检测陷入循环的消息 - 它们被传回源节点,然后源节点再次记录错误,依此类推。运行时将允许消息循环9次,然后记录另一个不可捕获的错误以打破循环。删除此属性将禁用检查。

如果消息在节点报告错误时已经有msg.error属性,则该属性将移动到msg._error

默认情况下,Catch 节点配置为由编辑器中同一选项卡上的所有节点触发,但也可以配置为目标选项卡上的特定节点。

如果同一选项卡上有两个 Catch 节点,并且它们都指向同一个节点,那么它们都将被该节点报告的任何错误触发。

如果 Catch 节点配置为由所有节点触发,它还可以配置为仅在尚未被另一个 Catch 节点捕获的错误上触发。这允许您创建针对特定节点的错误处理流程,并拥有一个将捕获“所有其他”的错误处理程序。

子流中的错误

如果子流内部记录了错误,运行时将首先检查子流内部是否有任何 Catch 节点。如果没有,错误将传播到包含子流实例的流程。

不可捕获的错误

这些是节点写入日志而未正确通知运行时的错误。它们无法使用 Catch 节点处理。

节点可能提供处理错误的替代方法。例如,通过更新其状态属性(可以使用 Status 节点监视)。它可能会正常发送消息,但设置一些额外属性以指示错误。

您可能需要联系节点的作者,看看是否可以更新它以正确记录错误。

uncaughtException 错误

这是特定类型的node.js错误,当节点未能正确处理内部错误时可能会发生。它们会导致整个 Node-RED 运行时关闭,因为这是唯一安全的做法。

这听起来可能很极端,但node.js 文档对此是这样说的

在未捕获的异常之后尝试正常恢复,类似于升级计算机时拔掉电源线。十有八九,什么都不会发生。但第十次,系统就会损坏。

典型的原因是节点启动了异步任务,并且该任务发生了错误。一个编写良好的节点将为该任务注册一个错误处理程序,但如果没有,则错误将未被捕获。

如果您遇到此类错误,则应尝试识别是哪个节点导致了错误并提出问题。由于错误的异步性质,这并不总是容易的。

Node-RED 日志中提供的堆栈跟踪将提供一些线索,说明发生错误的异步任务的性质,这反过来可能有助于您识别故障节点。

处理状态变化

并非所有错误条件都会显示为可被 Catch 节点捕获的错误事件。例如,MQTT 节点失去连接不会触发错误,但会触发其状态变化。

就像 Catch 节点可以用于处理错误事件一样,Status 节点可以用于处理节点状态的变化。

由 Status 节点发送的消息包含status属性,该属性提供有关状态和触发事件的节点的信息。

{
    "status": {
        "fill": "red",
        "shape": "ring",
        "text": "node-red:common.status.disconnected",
        "source": {
            "id": "27bbb5b1.d3eb3a",
            "type": "mqtt out"
        }
    }
}