CATCH node. Does it really help?

Ok, originally I was a bit confused about the CATCH node and why it only had an OUTPUT, but then it dawned on me.

It catches errors (by magic) and sends the report to the output node.

This sounds great! I can use it to catch errors on remote machines and send them back to my machine and I can look at them. Rather than remain confused about why things aren't working as they are expected.

But there is a catch (it seems) - excuse the pun.

IF you have a CATCH node, you don't get errors any more.

Originally you would look in the debug part and see the error.

Seems with the CATCH node, that doesn't happen.

So, as good as it is to tell you there are errors happening, when you go to that flow on that machine, the debug part doesn't give you any more information to what is happening.

Is there something I can do to also get the debug part?

Feed the output of the catch node into a debug node set to display the complete msg object!

1 Like

Yikes,

Alas I found something else which is "problematic" with it.

So (to get you back up to speed):
Remote machine. (or local)
This bit of code:

[{"id":"d10afd59.7dae3","type":"catch","z":"e2bd5a4e.5597e8","name":"","scope":null,"x":230,"y":920,"wires":[["c54da91.56dae58"]]},{"id":"b9382cba.6b5748","type":"mqtt out","z":"e2bd5a4e.5597e8","name":"ERROR_REPORT","topic":"","qos":"","retain":"","broker":"964d7beb.f4f8b","x":560,"y":920,"wires":[]},{"id":"c54da91.56dae58","type":"function","z":"e2bd5a4e.5597e8","name":"Set topic","func":"var device_name =global.get('myDeviceName');\nmsg.topic =\"ERROR_REPORT/\" + device_name + \"/\" + msg.topic;\nreturn msg;","outputs":1,"noerr":0,"x":380,"y":920,"wires":[["b9382cba.6b5748","ace59945.3ca778"]]},{"id":"16401c2.e2e2ee4","type":"inject","z":"e2bd5a4e.5597e8","name":"","topic":"","payload":"Test","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":870,"wires":[["c54da91.56dae58"]]},{"id":"ace59945.3ca778","type":"debug","z":"e2bd5a4e.5597e8","name":"Local Readings error message","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":600,"y":970,"wires":[]},{"id":"8b288b6b.d64498","type":"comment","z":"e2bd5a4e.5597e8","name":"Error catching","info":"","x":440,"y":860,"wires":[]},{"id":"3d5c3740.987da","type":"link in","z":"e2bd5a4e.5597e8","name":"ERROR RX","links":["1c6673bc.57897c","d8c75897.7610b","7e15b07e.eb6dd","6b0e8cc6.3f834c","fa5f1a1d.fe183","deb8cf5e.c79808","5d18e796.f6a298","90075991.04c27","118ad88b.ef1077","560ff4f0.8e9664","83436254.42b62","e963463e.8cf3b8","6bce9b2f.0d9fb4","8b2f6257.d125b8"],"x":275,"y":970,"wires":[["c54da91.56dae58"]]},{"id":"964d7beb.f4f8b","type":"mqtt-broker","z":"","broker":"192.168.0.99","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"20","cleansession":true,"willTopic":"EOM","willQos":"2","willPayload":"'MusicPi telemetry failure'","birthTopic":"SOM","birthQos":"2","birthPayload":"'Awaiting Music Pi'"}]

That sends any errors from that flow out on MQTT to another machine.
This code:

[{"id":"edaf301b.b4ce9","type":"mqtt in","z":"f9420cde.5b8bb8","name":"ERROR_REPORT","topic":"ERROR_REPORT/#","qos":"2","broker":"9ff4e9dd.66b6f","x":160,"y":610,"wires":[["64858c3.324fbf4","898f2be2.d36af"]]},{"id":"64858c3.324fbf4","type":"debug","z":"f9420cde.5b8bb8","name":"Message received","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":220,"y":690,"wires":[]},{"id":"9ff4e9dd.66b6f","type":"mqtt-broker","z":"","broker":"192.168.0.99","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"20","cleansession":true,"willTopic":"EOM","willQos":"2","willRetain":"true","willPayload":"'Tele Pi telemetry failure'","birthTopic":"SOM","birthQos":"2","birthPayload":""}]

Now, if I get an error on the first machine, I get a LOVELY message:

object
_msgid: "205aa237.87d78e"
topic: "ERROR_REPORT/TimePi/Door control flow"
payload: "TelePi_temp.db"
path: "/home/pi/.node-red/public/databases/machines/"
error: object
message: "Error: ENOENT: no such file or directory, stat '/home/pi/.node-red/public/databases/machines/TelePi_temp.db'"
source: object
id: "371d634b.a4f8f4"
type: "fs-ops-size"
name: ""
count: 1
stack: "Error: ENOENT: no such file or directory, stat '/home/pi/.node-red/public/databases/machines/TelePi_temp.db'↵ at Object.fs.statSync (fs.js:948:11)↵ at SizeNode.<anonymous> (/home/pi/.node-red/node_modules/node-red-contrib-fs-ops/fs-ops.js:401:31)↵ at emitOne (events.js:116:13)↵ at SizeNode.emit (events.js:211:7)↵ at SizeNode.Node.receive (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:215:14)↵ at FunctionNode.Node.send (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:202:14)↵ at sendResults (/usr/lib/node_modules/node-red/nodes/core/core/80-function.js:52:18)↵ at FunctionNode.<anonymous> (/usr/lib/node_modules/node-red/nodes/core/core/80-function.js:205:21)↵ at emitOne (events.js:116:13)↵ at FunctionNode.emit (events.js:211:7)↵ at FunctionNode.Node.receive (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:215:14)↵ at InjectNode.Node.send (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:137:22)↵ at InjectNode.<an..."
_event: "node:e963463e.8cf3b........

Slight trim at the end, but anyway......

That is nice as it tells me the machine, flow and the error.

At the other end of MQTT I get this:

object
topic: "ERROR_REPORT/TimePi/Door control flow"
payload: "TelePi_temp.db"
qos: 0
retain: false
_msgid: "3436edf3.1f6732"

Somewhat shorter and doesn't tell me the error.

Is it I am again missing something? Or does MQTT not send the entire message?

It has a bit of an impact on how things will work with the error handling part of the flows.

The mqtt out node does NOT send the entire msg object -- only the topic, payload, and _msgid fields. This is by-design (to avoid large http req/res blocks of potential circular data).

So your best bet is to use a change node to "move" bits you want to transmit into the payload field, before sending the caught msg to mqtt...

1 Like

shrickus,

Thanks much.

I guess that is obvious when you think about it, but....... As there are MQTT scripts that send entire pictures .....

But yes, I shall CHANGE the stuff I need to be on-sent.

Appreciated.

Sorry, but I've been trying.

The wording in the CHANGE node is confusing to me. (I think it is called Yoda logic) in how I am seeing it.

This is the ORIGINAL message (entire payload)

BedPi : msg : Object
object
payload: "BedPi_temp.db"
topic: "BedPi"
socketid: "lKlXaucSq5aF-5ZJAAD3"
_msgid: "b20265e6.2e1178"
_event: "node:580d2606.87b7a8"
path: "/home/pi/.node-red/public/databases/machines/"
error: object
message: "Error: ENOENT: no such file or directory, stat '/home/pi/.node-red/public/databases/machines/BedPi_temp.db'"
source: object
id: "6ace09cd.12f6e8"
type: "fs-ops-size"
name: ""
count: 1
stack: "Error: ENOENT: no such file or directory, stat '/home/pi/.node-red/public/databases/machines/BedPi_temp.db'↵ at Object.fs.statSync (fs.js:948:11)↵ at SizeNode.<anonymous> (/home/pi/.node-red/node_modules/node-red-contrib-fs-ops/fs-ops.js:401:31)↵ at emitOne (events.js:116:13)↵ at SizeNode.emit (events.js:211:7)↵ at SizeNode.Node.receive (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:215:14)↵ at FunctionNode.Node.send (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:202:14)↵ at sendResults (/usr/lib/node_modules/node-red/nodes/core/core/80-function.js:52:18)↵ at FunctionNode.<anonymous> (/usr/lib/node_modules/node-red/nodes/core/core/80-function.js:205:21)↵ at emitOne (events.js:116:13)↵ at FunctionNode.emit (events.js:211:7)↵ at FunctionNode.Node.receive (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:215:14)↵ at FunctionNode.Node.send (/usr/lib/node_modules/node-red/red/runtime/nodes/Node.js:202:14)↵ at sendResults (..."

Looking at it, there is the msg.payload and msg.error

In the CHANGE node I have it set to:
SET msg.error TO msg.payload

But when it comes out the other end of MQTT, it is not all there.

I've tried it the other way around too. Same result.
Just the TO messes with me.

To me it would be SET payload FROM error.

Sorry.
Maybe I am goofing with something, but I am on the right track - right?
I set the payload to the error.

SET msg.error TO msg.payload - msg.error is SET to the value in msg.payload

Ok, so if I want to put the msg.error in the payload part it would be the other way around.

The "ERROR" part has a few sub-things.
Source and Stack.

Will they be moved too?

Because when I had it the other way around (as I shall try again now) it didn't seem to send all the sub-structures.

(To "clarify"?) The message has a structure with the error, source and stack sub-entries.
Looking at the debug window they are nicely structured to work out WHAT the error is, WHERE the error is, and HOW the error happened.

After me CHANGING the message, I am finding a lot of that structure missing at the other end of the MQTT link.

This is a poor effort at the big picture:
I can't simulate (easily for you or myself) that there are two tabs/flows on the first machine.
I put the CHANGE node at the end of the flow at the last point before MQTT gets a hold of it.

The message is good there.
I see the structure as is should be.

When it goes through the MQTT a lot of the formatting/structure of the message is gone.

[{"id":"d2d575b.e713308","type":"catch","z":"b27802e.27fed","name":"","scope":null,"x":100,"y":880,"wires":[["1de4123f.2e9726","fb72809b.cb21c8"]]},{"id":"1de4123f.2e9726","type":"debug","z":"b27802e.27fed","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":230,"y":880,"wires":[]},{"id":"24a711b3.5ab3be","type":"fs-ops-size","z":"b27802e.27fed","name":"","path":"","pathType":"str","filename":"filename","filenameType":"msg","size":"filesize","sizeType":"msg","x":540,"y":690,"wires":[["271de747.6b378","572e7ff.0d10a"]]},{"id":"6c57eaa8.269b1c","type":"function","z":"b27802e.27fed","name":"Name of database + timestamp","func":"msg.filename = \"/home/me/.node-red/public/databases/machines/timepi_temp.db\";\nvar time = Date.now();\nvar x = msg.payload;\nmsg.payload = time + ' - ' + x;\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":690,"wires":[["24a711b3.5ab3be"]]},{"id":"5f0bd719.f132a","type":"inject","z":"b27802e.27fed","name":"","topic":"","payload":"clock","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":690,"wires":[["6c57eaa8.269b1c"]]},{"id":"271de747.6b378","type":"debug","z":"b27802e.27fed","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":700,"y":690,"wires":[]},{"id":"572e7ff.0d10a","type":"debug","z":"b27802e.27fed","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"filesize","x":700,"y":730,"wires":[]},{"id":"1871fd96.0e312a","type":"mqtt out","z":"b27802e.27fed","name":"","topic":"TEST","qos":"","retain":"","broker":"6ccf853d.6f8004","x":370,"y":930,"wires":[]},{"id":"9f989b81.a7ae68","type":"mqtt in","z":"b27802e.27fed","name":"","topic":"TEST","qos":"2","broker":"6ccf853d.6f8004","x":90,"y":1020,"wires":[["9295a769.63156"]]},{"id":"ebfd7d25.e9a658","type":"comment","z":"b27802e.27fed","name":"Part 1","info":"","x":380,"y":650,"wires":[]},{"id":"4ae5d697.d053d8","type":"comment","z":"b27802e.27fed","name":"Part 2  (New FLOW/Page)","info":"","x":370,"y":830,"wires":[]},{"id":"b22788c4.e9b9","type":"comment","z":"b27802e.27fed","name":"Part 2  (New FLOW/Page)","info":"","x":360,"y":730,"wires":[]},{"id":"93862085.35d9c","type":"catch","z":"b27802e.27fed","name":"","scope":null,"x":90,"y":770,"wires":[["3dfab9ec.b4196e"]]},{"id":"3dfab9ec.b4196e","type":"link out","z":"b27802e.27fed","name":"T1","links":["ea004038.c72ca8"],"x":185,"y":770,"wires":[]},{"id":"ea004038.c72ca8","type":"link in","z":"b27802e.27fed","name":"T2","links":["3dfab9ec.b4196e"],"x":135,"y":930,"wires":[["fb72809b.cb21c8"]]},{"id":"ed55fa65.1147d8","type":"comment","z":"b27802e.27fed","name":"Part 3 (New machine)","info":"","x":290,"y":970,"wires":[]},{"id":"9295a769.63156","type":"debug","z":"b27802e.27fed","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":230,"y":1020,"wires":[]},{"id":"fb72809b.cb21c8","type":"change","z":"b27802e.27fed","name":"Change","rules":[{"t":"set","p":"payload","pt":"msg","to":"error","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":240,"y":930,"wires":[["1871fd96.0e312a"]]},{"id":"13d447f2.9fc538","type":"comment","z":"b27802e.27fed","name":"Message good here","info":"","x":300,"y":770,"wires":[]},{"id":"99c448cf.bf2b98","type":"comment","z":"b27802e.27fed","name":"Message good here","info":"","x":410,"y":880,"wires":[]},{"id":"ecca1f4d.7c46","type":"comment","z":"b27802e.27fed","name":"Message NOT good here","info":"","x":430,"y":1020,"wires":[]},{"id":"6ccf853d.6f8004","type":"mqtt-broker","z":"","name":"192.168.0.99:1883","broker":"TimePi","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]

It'll take about 20 seconds to find out by trying it.

Use a Change node to either:

  1. Set msg.payload to msg.error
    or
  2. Move msg.error to msg.payload

Nick

go back and read @shrickus post then ask yourself the question:
"If I want to send multiple items of data, but can only send msg.payload, how can I put multiple items of data into msg.payload?"

HINT (and homework) go read https://nodered.org/docs/user-guide/messages

Yes, that is what I did.

So I need to SET the msg.payload to the error part of the message.
The error part has nicer structure.

I know I am going to get shot for missing something but here are some screen shots explaining/showing what I am doing.

Now I can see that the error name isn't showing on the shot. Maybe I scrolled up a bit too far.
But you can see the sub-structures displayed.

This is the settings in the CHANGE node:

So you can see the structure is still there.

Now (last one) is when it comes out of MQTT.

All that structure is gone.

I'll go and read it again, but something isn't "clicking" for me.

Quick answer - add a JSON node after the MQTT In node to parse that String payload back to the Object form you passed the original MQTT node.

The MQTT Out node will automatically JSON encode an object. The MQTT In node doesn't know about the different types of payload - it just passes on what it gets. So you have to explicitly decode the JSON String back to an Object.

1 Like

Thank you very much.

I was nearly there - yeah, I know that sounds slack.

It is now at a better stage than it was at the start. I just need more parsing of the errors down steam of that.
As I have no idea what they will/could be, it is a bit vague. I have one catch working though.

22:50, I think it is time for bed today.