Online Book Reader

Home Category

AppleScript_ The Definitive Guide - Matt Neuburg [163]

By Root 1652 0
or it throws error 1001 to signal that the user cancelled. It's up to the caller to decide how to proceed based on on this report. This particular caller has a different dialog ready to show the user in case of either error, and is perfectly prepared to loop all day until the user enters something in the dialog. But all of that is the caller's own decision; the handler itself just performs the single task for which it was written. Distribution of responsibilities makes for more reusable code, and the example shows how throwing errors contributes to this.

A common technique in an error handler is to handle only those errors that are in some sense yours—those that you expect and are prepared to deal with. Unexpected errors are simply allowed to percolate on up the call chain, possibly all the way to AppleScript, causing the script to terminate; this makes sense because they're unexpected and you're not prepared to deal with them. There are two ways to accomplish this.

One way is to catch all errors and then rethrow any errors you aren't prepared to handle. If you're going to do that, you should probably use all the parameters, both in the on error line as you catch the error and in the error command as you rethrow it; otherwise you might strip the error of some of its information, which might reduce its value to the user (or to any code at some higher level that catches it).

In this example, we ask the user for the number of a disk to get the name of. If the number is not the number of an existing disk, the Finder throws error number -1728, so if we get an error and that's its number, we deliver a meaningful response. If we get any other error—for example, the user enters text in the dialog that can't be coerced to a number—we rethrow it and let AppleScript inform the user that this is not an integer.

set n to text returned of ¬

(display dialog "What disk would you like the name of?" default answer "")

try

tell application "Finder" to set x to name of disk (n as integer)

display dialog x

on error e number n partial result p from f to t

if n = -1728 then

display dialog "I don't think that disk exists. " & e

else

error e number n partial result p from f to t

end if

end try

The other approach is to use a filtered error handler. In this approach, some of the parameters in the on error line are not variable names but literals. AppleScript will call the error block only if all such literals are matched by the corresponding error parameter value. Otherwise, the error percolates up the call chain, of its own accord.

Thus, we can rewrite the entire error block from the previous example in a much briefer form, as follows:

on error e number -1728

display dialog "I don't think that disk exists. " & e

end try

There's no way to list alternative literals; you can't write an error block that catches errors with either of just two particular error numbers, for instance. A workaround is to nest try blocks. To illustrate, here's the same example again, but this time we'll catch both error -1728 (no such disk) and error -1700 (not an integer).

set n to text returned of ¬

(display dialog "What disk would you like the name of?" default answer "")

try

try

tell application "Finder" to set x to name of disk (n as integer)

display dialog x

on error e number -1728

display dialog "I don't think that disk exists. " & e

end try

on error e number -1700

display dialog "I don't think that was an integer."

end try

If you don't like the look of literally nested try blocks ("lexical nesting "), you can nest them by means of the calling chain ("dynamic nesting "):

on askUser( )

set n to text returned of ¬

(display dialog "What disk would you like the name of?" default answer "")

try

tell application "Finder" to set x to name of disk (n as integer)

display dialog x

on error e number -1728

display dialog "I don't think that disk exists. " & e

end try

end askUser

try

askUser( )

on error e number -1700

display dialog "I don't think that was an integer."

end try

An expired timeout (see "Timeout," earlier

Return Main Page Previous Page Next Page

®Online Book Reader