`osascript` with timeout error handling

I realize that I can break this out into calling a separate AppleScript to do what I want, but in the interest of keeping all of the logic in one shell script file, I am asking if this is possible:

Right now I have a shell script where I’m detecting an error condition, shutting down a bunch of apps with osascript, and then re-starting the apps. In the section of shutting down apps, this is the offending line:

osascript -e 'tell application "Sonos" to quit'

For whatever reason, Sonos times out about 20% of the time, and I’m struck with an error -1712 which stalls the rest of the shell script:

image

Is there any way to include a try or other error handling in that osascript line? (can you do a one-liner try?) As I understand it, the AppleScript timeout is hard coded, so I can’t make the timeout longer on that command. (Please correct me if I’m wrong!)

Basically if Sonos doesn’t quit, I don’t really care that much (It likely has quit, just took a long time, and I’m about to restart it), and I definitely don’t want it to block the rest of the script.

I suppose the most expedient way to deal with it would be on the shell script side, using Homebrew coreutils gtimeout to kill the osascript if it hangs:

gtimeout 20s osascript -e 'tell application "Sonos" to quit'

…but I’d rather not do that if I can more cleanly deal with the error in the AppleScript portion. Ideas?

You can execute multi-line scripts with osascript by including multiple -e keys.

osascript -e 'repeat 3 times' -e 'try' -e 'beep doggy' -e 'on error e' -e 'say e' -e 'end try' -e 'end' 

So something like

osascript -e 'tell application "System Events"' -e 'set maxLoops to 100' -e 'repeat while (name of every application process) contains "Sonos"' -e 'try' -e 'tell application "Sonos" to quit' -e 'exit repeat' -e 'set loopCount to loopCount + 1' -e 'end try' -e 'if loopCount > maxLoops then exit repeat' -e 'end repeat' -e 'end tell' 

Also, for future reference,

with timeout of 120 seconds
	tell application "Sonos"
		quit
	end tell
end timeout```
1 Like

this may also work:

set osaScript to "-e 'tell application \"System Events\"' -e 'try' -e 'tell application \"Sonos\" to quit' -e 'end try' -e 'end tell' -e"
1 Like

Oho! I didn’t realize that multiple -e keys was a thing! And the timeout change! Thanks, that makes this simpler.

I think the default timeout is already 120 seconds so you may want to use a larger number