:local addrlst [/ip firewall address-list find where comment=$d disabled=no]
# some more irrelevant code here
:local rrlst [/ip firewall address-list find where address=$d dynamic=no disabled=no]
And my mailbox get spammed with notifications about no such item (4) script error randomly. Every few minutes (during that time those instructions are called several hundreds or maybe even thousands times). I verified that script always crashes on one of those two lines.
I know this error is due to fact that ROS is “forgetting” some dynamiic entries during script execution but thiis is basically single, atomic instruction. How can I do some workaround? My goal is to get list of IPs that ROS resolved fqdn based address-lists to (script is basically flushing DNS cache and removing all dynamic entries forcing ROS to resolve address-lists again whenever there’s some synchronization issue between. Synchronization is checked by performing manual DNS resolution against specified server and comparison every 2 seconds)
I did that. I mean not exactly that but I put :log debug message=N where N was some number and I put it every line, then I browsed through syslog logs to see after which log script stops and throws “no such item (4)” and like I said it’s always one of those 2 lines.
Here’s full script (just without those debug logs to not spam):
It’s worth to note that on-error doesn’t catch “no such iitem (4)” error. I’ve noticed it multiple times because I started using try-catch for whole scripts and still I receive from time to time “no such item (4)” errors from some scripts.
If you wrap the script in {} and past it to the terminal, its easier to see where things go wrong.
Same with put instead of log. All on screen when things are running.
Also split the scripts up in parts and cut/past part by part to terminal.
It may be that the table are to large and some is change in beweeen when script are running so things get lost and gives error.
I do see that they suggest to use foreach
Your issue probably is that some of your DNS-derived address list items have really short TTL (like when you try to get addresses of CDN servers in an address list), and there is a reasonable chance that your find retrieves a list of items where some of them expire some milliseconds later and the next usage indicates that they are missing.
One would indeed expect that for a single command line this “cannot happen”, but on the other hand it is good that the router uses multitasking and address list expiry can happen simultaneously with script execution. You would not want to block the expiry during any execution of a script.
I agree with you that there should be some way to catch those errors, preferably just using on-error= or otherwise by setting some mode where such errors are just ignored for the script.
Yeah, I don’t want to just skip sending alerts about script errors because while this script is not really all that mission critical there are other script on router that monitor various aspects of network and they’re more stateful so error in them could leave script in “undefined behavior” state and may require manual cleanup. It doesn’t happen often but once every few weeks. Now this one script is spamming my mailbox with “no such item (4)” errors and I don’t know which errors are from this one and which are from more important scripts
I already filed “bug request” to mikrotik if they could maybe at least add in log indication which script crashed, and even better in which line - this way I could just set up filter in mailbox to ignore crashes of this one particular script that is not really all that critical.
With “I agree with you that there should be some way to catch those errors, preferably just using on-error= or otherwise by setting some mode where such errors are just ignored for the script.” of course I mean that this ignore action is only for the current script or current function in a script, not globally.
The on-error= clause is already local. It is unfortunate that this does not catch the “no such item” error, that is imho a bug that should be fixed.
There are other topics on the forum where people encounter unpredictable “no such item” errors (due to race conditions) and cannot handle them in a reasonable way.
W.r.t. printing the line number of an error: the issue is that scripts are “compiled” from the text that you type into a stack-based intermediate language which is then executed by the script engine. The engine sees only the compiled code, not the original lines. So when an error occurs, it is only known in what instruction it happens but not which line this came from.
Under certain conditions you can see this intermediate code in the environment variables, e.g. when you define a function and then print the environment. You will see that there is no line-number information in this intermediate code.