Yepp, I agree with the approach -thanks, again! I may have been unclear in the meantime but in the beginning (see first post) I mentioned that I have a problem in that function due to this error:
"TypeError: cannot read property 'spectrum' of undefined".
I agree.
The node is trying to read the context and it isn't set.
Ok, different approach:
Stick a switch
node just before it and that checks if the flow.context
is ... defined.
Or: not null
(Sorry brain shutting down as it is 22:58 local)
And so only if the flow.context
is valid will the message pass.
You could put a second output to the switch
node and then stick code that tells you that the context
wasn't set.
That may be a way to go.
It would (should) also stop errors happening as only if the context
is set will the node get the message.
What is a rogue message?
I can't say.
But if a message happens that somehow corrupts the environment..... You need to find this message and control what is happening.
That's caught as well in FileSeparate_Diagram:
try{
msg.index=null;
var obj = JSON.parse(msg.payload);
node.warn("fxModel:"+msg.payload);
flow.set("fxModel",obj);
node.warn("ch length:"+obj.channels.length);
flow.set("channels_length",obj.channels.length);
flow.set("ch_0",obj.channels[0]);
flow.set("ch_1",obj.channels[1]);
flow.set("ch_2",obj.channels[2]);
flow.set("ch_3",obj.channels[3]);
flow.set("ch_4",obj.channels[4]);
flow.set("ch_5",obj.channels[5]);
flow.set("ch_6",obj.channels[6]);
flow.set("ch_7",obj.channels[7]);
flow.set("spectrum_bins", obj.spectrum_bins);
flow.set("slider_cp_0",flow.get("slider_0"));
flow.set("slider_cp_1",flow.get("slider_1"));
flow.set("slider_cp_2",flow.get("slider_2"));
flow.set("slider_cp_3",flow.get("slider_3"));
flow.set("slider_cp_4",flow.get("slider_4"));
flow.set("slider_cp_5",flow.get("slider_5"));
flow.set("slider_cp_6",flow.get("slider_6"));
flow.set("slider_cp_7",flow.get("slider_7"));
}catch(e){
node.warn(e.stack);
flow.set("channels_length",0);
}
return msg;
This is not exactly the same but this shall catch if the json is not ok. But if it's ok, the object properties shall be fine.
Sorry, that code is way above my skill set.
Never mind and thanks for all your suggestions!
No problems.
Good luck.
I meant what is your definition of a rougue message?
Oh, gotcha!
Sorry.
Well say the code is written to parse messages of a certain syntax/structure.
Because of link
nodes and other things, you lose track of the messages and who is connected to whom.
A piece of code occasionally sends out a message which isn't of that structure and isn't meant to be in this part of the code.
It arrives and.... The code - as given - spits the dummy.
Here is an example of just that happening and the double whammy that had me stumped for months.
[{"id":"55752315.00485c","type":"mqtt in","z":"a1911aa3.c45be8","g":"48ec7aa8.65cb1c","name":"","topic":"TELEPI_LOCAL/tele_led/","qos":"2","datatype":"auto","broker":"1ecd3a9e.dc5bfd","x":2810,"y":350,"wires":[["305b2df2.c6b6f2","9cbdf8e0.e07d48"]]},{"id":"9cbdf8e0.e07d48","type":"switch","z":"a1911aa3.c45be8","g":"48ec7aa8.65cb1c","name":"Only rgb messages","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Stop","vt":"str"},{"t":"eq","v":"Heartbeat","vt":"str"},{"t":"cont","v":"rgb","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":3110,"y":350,"wires":[[],[],["878cc5.e3b7d338"]]},{"id":"878cc5.e3b7d338","type":"switch","z":"a1911aa3.c45be8","g":"48ec7aa8.65cb1c","name":"Not empty","property":"payload","propertyType":"msg","rules":[{"t":"nempty"}],"checkall":"true","repair":false,"outputs":1,"x":3245,"y":350,"wires":[["185d3c73.d58054","4ceea5fb.370db4","67ec3b8f.0b4ab4"]],"l":false},{"id":"185d3c73.d58054","type":"string","z":"a1911aa3.c45be8","g":"48ec7aa8.65cb1c","name":"","methods":[{"name":"delLeftMost","params":[{"type":"str","value":"rgb,"}]},{"name":"left","params":[{"type":"num","value":"1"}]},{"name":"toInteger","params":[]}],"prop":"payload","propout":"pointer","object":"msg","objectout":"msg","x":3350,"y":350,"wires":[["13c2f958.760b9f"]]},{"id":"13c2f958.760b9f","type":"string","z":"a1911aa3.c45be8","g":"48ec7aa8.65cb1c","name":"0","methods":[{"name":"chompLeft","params":[{"type":"str","value":"rgb"}]},{"name":"delLeftMost","params":[{"type":"str","value":","}]},{"name":"delLeftMost","params":[{"type":"str","value":","}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":2750,"y":420,"wires":[["79ca3d07.dd1f6c","e014241f.0a93c8","d0bb44bf.d3a558"]]},{"id":"79ca3d07.dd1f6c","type":"function","z":"a1911aa3.c45be8","g":"48ec7aa8.65cb1c","name":"Problematic node","func":"let pointer = msg.pointer;\nlet payload = msg.payload;\n\nflow.set(\"LEDSTRIP[\"+pointer+\"]\",payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2920,"y":420,"wires":[[]]},{"id":"1ecd3a9e.dc5bfd","type":"mqtt-broker","name":"LOCAL MQTT","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"SOM","birthQos":"0","birthPayload":"TelePi comms UP","birthMsg":{},"closeTopic":"EOM","closePayload":"TelePi shutting DOWN","closeMsg":{},"willTopic":"EOM","willQos":"0","willPayload":"TelePi Comms FAILURE","willMsg":{},"sessionExpiry":""}]
Node/s of interest:
the only rgb messages
and the problematic node
.
The code is now working.
Originally the third output was otherwise
, not contains rgb
.
The first two messages (stop
and heartbeat
) are valid on that topic as they are used to control things.
(Python script: stop
tells it to stop.)
heartbeat
is an ongoing message to control output.
Every day I would get a message and for a long time I simply had problematic node
disabled.
What it provided wasn't mission critical but would be nice to have working.
So to recap: Just about daily it would give an error if enabled and active.
The other day I did something and forced a restart of the scripts.
There it is! The problem!
I got a rogue message.
Thus I changed the third output to contains rgb
because I didn't realise this other message would happen/appear here.
I changed it and now all things are good, and the node doesn't error.
WEIRD BONUS!
Daily (even with that node disabled) I would get a report that my WAP was going down at 05:00 then comes back.
DAILY!
Today: it hasn't. So I fixed two problems with one thing.
I'll have to investigate that more. Both how the rogue message is sneaking in and how it was causing the WAP to appear to go down daily at 05:00.
But this is a 100% good example how things that you see have nothing in common can cause unexpected results.
Oh: P.S.
The rogue message was a new day
message that should happen at 00:00. Not 05:00.
Oh, quick/dumb question.
If/when this happens what do you want to happen?
- Is it ok to just let the message go and do nothing
or do you want
- Is it that the message has to be received to make something happen and so MUST be received?
Just depending on which one is needed has a profound change on what happens next.
Preferably, the message shall be processed. That subflow on the picture logs a certain activity of the system and it's not nice if certain entries are missing as you don't know what happened at that point. Of course, the failure can be logged as well to put at least something in the log to indicate that we know that a certain activity did happen but we could not create a log entry for it and we just let the system go on.
Ok. No problems.
So the event needs to get a result.
It is just that sometimes you can just let it slide. That is a very easy route, but has it's own set of limitations.
I'm out of ideas for now.
But I would be interested in developments.
(Off topic a bit)
I don't know if you read my big post a couple back.
Some weird things were happening to my flows and believe me catching the cause was painful and slow.
But you can't rule anything out. As soon as you do that you are leaving yourself in the position where something you haven't considered can really bite you when you finally discover the cause.
The point one needs to get with an issue is to make it reproducible. Afterwards, it's just a matter of time to figure it out
Yup.
But even that can be painfully slow as you don't know what it is that is causing it.
When the context
is not set/valid:
Is there a default you could use?
Is the original (what is supposed to be in the context
) still somewhere?
I can only agree but you know: baby steps... One after the other. If I looked already that far, I'd have already given up.
No problem.
I am only spit balling.
I strongly suggest you make a log of the context
and have it time stamped so you can see as it happens.
Then when the error happens - and is logged, etc - you can compare that to the log and see what is happening.
Alas this is going to take a lot of disc space and an unknown amount of time.
Good luck with it.
Yepp, I know Thanks!
It seems there's an issue when changing and deploying the parent subflow. I have not yet managed to find the right sequence but today in the morning I managed to reproduce it by chance when modifying the subflow, copying it to create a new instance, modifying again, deleting the previously copied instance, etc. Strangely enough, after the deploy some instances of the parent subflow worked but one did not. I have only the relevant log that shows what happened (row numbering added by me):
- Dec 3 08:28:58 raspberrypi Node-RED[341]: 3 Dec 08:28:58 - [warn] [function:FileSeparate_Diagram] ch length:6
- Dec 3 08:28:58 raspberrypi Node-RED[341]: 3 Dec 08:28:58 - [warn] [function:calculate channel sum] channels_length:undefined
- Dec 3 08:28:58 raspberrypi Node-RED[341]: 3 Dec 08:28:58 - [warn] [function:calculate channel sum] ch_0:undefined
- Dec 3 08:28:58 raspberrypi Node-RED[341]: 3 Dec 08:28:58 - [error] [function:calculate channel sum] TypeError: Cannot read property 'spectrum' of undefined
Row 1. shows that the flow context variable 'channels_length' set in the parent subflow in function node 'FileSeparate_Diagram' has a certain value (which is 6):
node.warn("ch length:"+obj.channels.length);
flow.set("channels_length",obj.channels.length);
flow.set("ch_0",obj.channels[0]);
Row 2-3. show that the same flow context variables are undefined when accessed in a subflow of the parent subflow called 'calculate channel sum':
node.warn("channels_length:"+flow.get("$parent.channels_length"));
node.warn("ch_0:"+JSON.stringify(flow.get("$parent.ch_0")));
Row 4. shows the error as a result of these.
Does this give a clue to you what can go wrong with the subflows?
Could it be that you haven't / aren't pre-defining stuff in the subflows?
So on initial invocation they fail.
But subsequently they don't because the variable (context) is set.