如何绕过索引错误或再次使用脚本 运行?

How can I bypass an index error or have the script run again?

我遇到了一个索引错误,当正在使用的应用程序出现叠加层或通知时会出现该错误。为了提供更好的描述,如果需要确认或忽略某些内容,该应用程序会偶尔显示警报。发生这种情况时,脚本无法 return GUI 中指定位置的值,并且 return 出现以下错误消息:"Can’t get group 4 of toolbar 1 of window 1 of process " 我正在使用的应用程序”。无效 index.System 事件出错:无法获取进程 "App I'm Using" 的 window 1 的工具栏 1 的第 4 组。索引无效。(-1719)"

该行为是预期的,但我想将脚本调整为延迟重试 30 秒左右,或者根本不显示所述错误。

我一直在尝试使用 'on error' 语句,但我无法让它与它所指的 'tell' 语句一起使用,例如:

    on error error_message number error_number
        if error_number = -1719 then
            wait 30
        end if

我不确定如何将 'on error' 函数与下面的脚本部分一起使用,但如果我可以让它在 30 - 45 秒内重试而不显示错误,那就是完美。

on idle
    -- Update the status item's text here.
    tell application "System Events"
        if not (exists process appName) then
            display alert "Application " & appName & " is not running" as warning giving up after 6
            quit me
        end if
        tell process appName
            tell first window's first toolbar's fourth group's first group's first menu button
                set activityState to first item of (value as list) as text
            end tell
        end tell
    end tell
end idle

我相信当脚本到达 "tell window's first toolbar's fourth group's..." 之前遇到错误时,它应该 "set activityState to first item..."。

我已经成功地将 'on error' 函数与 'try' 语句一起使用,但是我在使用这个函数时遇到了问题。

您不能拆分语句(例如 iftell)。 try 语句需要包含您希望它使用的完整语句,例如,告诉应用程序进程的语句:

on idle
    tell application "System Events"
        if not (exists process appName) then
            ---
        end if
        try
            tell process appName
                ---
            end tell
        on error errmess number errnum
            return 30 -- try the idle handler again in 30 seconds
        end try
    end tell
end idle

您可以使用 exists 关键字来检查元素是否存在,然后再尝试访问它。 exists 如果该元素不存在,则不会通过错误,并且会让您跳过有问题的行:

on idle
    -- Update the status item's text here.
    tell application "System Events"
        if not (exists process appName) then
            display alert "Application " & appName & " is not running" as warning giving up after 6
            quit me
        end if
        tell process appName
            -- assuming the window and toolbar are always going to be there
            try
                tell first window's first toolbar
                    -- check to see if the UI element exists
                    if exists fourth group's first group's first menu button then
                        -- only get the activity state if it does
                        tell fourth group's first group's first menu button
                            set activityState to first item of (value as list) as text
                        end tell
                    end if
                end tell
            on error errstr
                (*
                  this code is in an 'idle' handler, so on any error we
                  just return 30 to idle for another 30 seconds and try again.
                 *)
                return 30
            end try
        end tell
    end tell
end idle

或者您可以尝试这种方法,该方法将保留在重复循环中,直到 first window's first toolbar's fourth group's first group's first menu button 可用。

on idle
    -- Update the status item's text here.
    tell application "System Events"
        if not (exists process appName) then
            display alert "Application " & appName & " is not running" as warning giving up after 6
            quit me
        end if
        tell process appName
            repeat until exists of first window's first toolbar's fourth group's first group's first menu button
                delay 0.2
            end repeat
            tell first window's first toolbar's fourth group's first group's first menu button
                set activityState to first item of (value as list) as text
            end tell
        end tell
    end tell
end idle