Whilst it is easy to create flows that do the right thing when everything works, it is also important to think about what could go wrong.
For example, if the flow interacts with an external database or API, what happens if it stops responding to requests? Or what if the MQTT nodes lose their connection to a broker?
Error handling in any application is essential to ensure these sorts of events are handled properly. What it means to handle the error will depend on the requirements of the application. You may want to try an action that failed, or trigger a separate alert, or maybe the error is an entirely expected event that is just another part of the application logic.
Node-RED provides two ways for a node to report an error. It can either just write a message to the log or it can notify the runtime of the error and cause a flow to be triggered.
If the error is only written to the log, you will see the message in the Debug sidebar and log output, but you will not be able to create a flow to handle it. These are uncatchable errors.
If it does notify the runtime properly, then it is a catchable error that can be used to trigger an error-handling flow.
There is a third sort of error that can cause the Node-RED runtime to shutdown. These
uncaughtException
errors cannot be handled in the flow and are caused by bugs
in nodes.
This guide describes each of these error types in more detail and shows what can be done to handle them. It also looks at how the Status events of a node can be used to create flows that handle unexpected events.
When a node logs an error, it will appear in the Debug sidebar.
This shows the error message, the date/time of the error, and the node that logged the error. As with other Debug messages, hovering over it will highlight the node in the workspace. If it isn’t in the current view, then clicking on the node’s name in the top corner will reveal it in the workspace.
If a node notifies the runtime of an error then the Catch node can be used to create a flow to handle it.
If an error is caught by a Catch node, it will not be logged to the Debug sidebar.
The message sent by the Catch will be the message provided by the node reporting
the error. This message will have an error
property set that provides information
about the error:
{
"topic": ...,
"payload": ...,
"error": {
"message": "An error",
"source": {
"id": "2e25823d.fa3f7e",
"type": "function",
"name": "My Function",
"count": 1
}
}
}
The properties of msg.error
are:
msg.error
:
message
- the error messagesource
- information about the node logging the error:
id
- the source node idtype
- the type of the source nodename
- the name, if set, of the source nodecount
- how many times this message has been thrown by this node.
This property is used by the runtime to detect messages stuck in a loop - where
they are passed back to the source node which then logs the error again, and so on.
The runtime will allow a message to loop 9 times before logging another,
uncatchable, error to break the loop. Deleting this property will disable the check.If the message already had a msg.error
property when the node reported the error,
that property will be moved to msg._error
.
By default, the Catch node is configured to be triggered by all nodes on the same tab in the editor, but it can also be configured to target specific nodes on the tab.
If you have two Catch nodes on the same tab and they both target the same node, then they will both be triggered by any errors reported by that node.
If a Catch node is configured to be triggered by all nodes, it can also be configured to only trigger on errors that have not already been caught by another Catch node. This allows you to create error handling flows that target specific nodes and also have an error handler that will catch “everything else”.
If an error is logged from inside a subflow, the runtime will first check for any Catch nodes inside the subflow. If there are none there, the error will propagate up to the flow containing the subflow instance.
These are the errors a node writes to the log without notifying the runtime properly. They cannot be handled using the Catch node.
The node might provide alternative ways for handling the error. For example, by updating its status property (which can be monitored with the Status node). It may send a message as normal but with some additional property set to indicate the error.
You may want to contact the node’s author to see if it can be updated to log the error properly.
uncaughtException
errorsThese are a particular type of node.js error that can occur when a Node fails to properly handle an internal error. They cause the entire Node-RED runtime to shutdown as that is the only safe thing to do.
It may sound extreme, but here is what the node.js documentation says about it:
Attempting to resume normally after an uncaught exception can be similar to pulling out the power cord when upgrading a computer. Nine out of ten times, nothing happens. But the tenth time, the system becomes corrupted.
The typical cause will be that a node has kicked off an asynchronous task and that task has hit an error. A well-written node will have registered an error handler for that task, but if there isn’t one, the error will go uncaught.
If you encounter this type of error then you should attempt to identify which node caused the error and raise an issue against it. This is not always easy due to the asynchronous nature of the error.
The stack trace provided in the Node-RED log will provide some clues as to the nature of the asynchronous task that hit the error, which in turn may help you to identify the node at fault.
Not all errors conditions will appear as error events that can be caught be a Catch node. For example, the MQTT nodes losing their connection will not trigger an error, but they will trigger a change of their status.
Just as the Catch node can be used to handle error events, the Status node can be used to handle changes in a node’s status.
The message sent by the Status node includes the status
property that gives
information about the status and the node that triggered the event.
{
"status": {
"fill": "red",
"shape": "ring",
"text": "node-red:common.status.disconnected",
"source": {
"id": "27bbb5b1.d3eb3a",
"type": "mqtt out"
}
}
}
Node-RED: Low-code programming for event-driven applications.
Copyright OpenJS Foundation and Node-RED contributors. All rights reserved. The OpenJS Foundation has registered trademarks and uses trademarks. For a list of trademarks of the OpenJS Foundation, please see our Trademark Policy and Trademark List. Trademarks and logos not indicated on the list of OpenJS Foundation trademarks are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
The OpenJS Foundation | Terms of Use | Privacy Policy | OpenJS Foundation Bylaws | Trademark Policy | Trademark List | Cookie Policy