script debugging?

What behaviors should I expect when the script encounters an error (syntax error, runtime error etc)? Does it continue or abort? And will there be any output if not explicitly specified in the script with log command?

When I print the script I see “Flags: I - invalid” but there is no syntax error. And I also noticed run count increments even if there are syntax errors. That can get quite confusing.

AFAIK, when you run a script, if there’s a parse time error, the whole script will abort. If it’s a post-parse time, all lines before the offending line will run normally, and the fatal one will show either a syntax error or runtime error, after which the whole script terminates.

Stuff like mismatching parenthesis, misquoted strings and improperly escaped characters are all examples of parse time errors. Stuff like missing arguments, non-existent menus/commands are all examples of post-parse syntax errors. Stuff like missing values (e.g. targeting an interface that doesn’t exist) or not having sufficient permissions are post-parse runtime errors.

I think the “I” flag in “/system script” refers to a parse time error. If you try to run the script from the command line, you should see on screen where the parse error is at. Winbox doesn’t show error messages.

Here is the script, no error shown when I printed it in terminal

If there is an error where can I see the error. Parse time errors are not shown in system log.

:global ddnsuser "username"
:global ddnspass "password"
:global theinterface "ether1-gateway"
:global ddnshost ddns.example.com
:global ipddns [:resolve $ddnshost];
:global ipfresh [ /ip address get [/ip address find interface=$theinterface ] address ]
:if ([ :typeof $ipfresh ] = nil ) do={
   :log info ("DynDNS: No ip address on $theinterface .")
} else={
   :for i from=( [:len $ipfresh] - 1) to=0 do={ 
      :if ( [:pick $ipfresh $i] = "/") do={ 
    :set ipfresh [:pick $ipfresh 0 $i];
      } 
}
 
:if ($ipddns != $ipfresh) do={
    :log info ("DynDNS: IP-DynDNS = $ipddns")
    :log info ("DynDNS: IP-Fresh = $ipfresh")
   :log info "DynDNS: Update IP needed, Sending UPDATE...!"
   :global str "/nic/update\?hostname=$ddnshost"
   /tool fetch address=dyn.dns.he.net src-path=$str mode=https check-certificate=yes user=$ddnsuser \
         password=$ddnspass dst-path=("/DynDNS.".$ddnshost)
    :delay 1
    :global str [/file find name="DynDNS.$ddnshost"];
    /file remove $str
    :global ipddns $ipfresh
  :log info "DynDNS: IP updated to $ipfresh!"
    } 
#else={
#     :log info "DynDNS: dont need changes";
#    }
}

There doesn’t seem to be a syntax error here… Certainly not a parse time one.

I can add it to “/system script” with no problem, and I don’t see any “I” flag… It seems that flag there refers to something else. Try to copy and paste the source into a new script, and remove the old one.

Again, to see any errors, run the script from the command line (i.e. “Terminal”, see the “New Terminal” button in Winbox):

/system script run scriptName

(where “scriptName” is the name of the script, of course)

Thanks for the info.

I created a new script and still see the I flag.

[admin@MikroTik RB750G] /system script> print from=test
Flags: I - invalid 
 0   name="test" owner="admin" run-count=0 source=

That’s not a flag… That’s a legend for flags IF they appear.

If the script was flagged, you’d see the flag next to the number, e.g.

Flags: I - invalid
 0 I   name="test" owner="admin" run-count=0 source=

It’s easier to see this in other menus with multiple flags… say

[admin@MikroTik] > /ip firewall filter print from=0
Flags: X - disabled, I - invalid, D - dynamic 
 0 X  ;;; place hotspot rules here
      chain=unused-hs-chain action=passthrough log=no log-prefix=""

The “X” next to the 0 indicates the item is disabled, while the “X” on the line that starts with “Flags:” simply tells you that “X” stands for “disabled”, while “I” stands for “invalid”, and “D” stands for “dynamic”. If an item was for example dynamic and invalid, the rule would’ve looked like:

[admin@MikroTik] > /ip firewall filter print from=0
Flags: X - disabled, I - invalid, D - dynamic 
 0 ID  ;;; place hotspot rules here
      chain=unused-hs-chain action=passthrough log=no log-prefix=""