I don't use DEVON-related software, but in ordinary1 situations when dealing with AppleScript records, CRGreen's suggestions won't apply: exists is not a command that properties understand, especially non-existent properties; and referencing a property that does not exist will throw an error.
I'm glad you're looking for an alternative to try...end try. I've seen your previous code samples that are drowning in them, and they are expensive operations when an error is caught, so not ideal for what you're attempting. try really has no place in AppleScript at all.
Rather than testing for the existence of a property within a record, the way to approach this in a general context is to create a record object that contains all the property values that would ever be needed, and to assign default values to each of them.
In AppleScript, a record is observed to follow the following behaviour:
A single record object can only contain one property with a given identifier. Should you attempt to insert two properties both of which are identified the same, the compiler will keep the first property and its associated value, and scrub the rest:
{a:1, b:2, a:3} # will resolve on compilation immediately to {a:1, b:2}
Two record objects can contain properties with shared identifiers, like so:
set L to {a:1, b:2, c:3}
set R to {d:missing value, c:L}
Similarly to list objects, two record objects can be merged into a single record, and the properties will be amalgamated: properties with identifiers unique to each record will simply be inserted without any change into the resulting data structure. Where an identifier occurs in both record objects before the merge, again, precedence is given in a left-to-right reading order, so the properties in the prefixed record (on the left) will prevail and the suffixed record (on the right) will have its non-unique property identifiers (and their values) scrubbed:
L & R --> {a:1, b:2, c:3, d:missing value}
R & L --> {d:missing value, c:{a:1, b:2, c:3}, a:1, b:2}
Your code snippet contains this:
repeat with g in (children of root of (think window 1))
set theAnnotation to annotation of g
end
Therefore, g is an item contained within children (a list object), and the type class of g is a record. Depending on which item of children is being examined, I'm assuming that some of those items are records that do contain a property identified by annotation, and some of those items are records that do not contain such a property.
However, consider the following record that results from this merge:
g & {annotation:missing value}
Here are the two possible scenarios:
g is a record that already contains a property identified as annotation, e.g.:
set g to {cannotation:"doe", bannotation:"ray", annotation:me}
g & {annotation:missing value} --> {cannotation:"doe", bannotation:"ray", annotation:«script»}
set theAnnotation to annotation of (g & {annotation:missing value})
--> «script» (i.e. me)
OR:
g is a record that in which the property identifier annotation does not exist, e.g.:
set g to {doe:"a deer", ray:"a drop of golden sun"}
g & {annotation:missing value} --> {doe:"a deer", ray:"a drop of golden sun", annotation:missing value}
set theAnnotation to annotation of (g & {annotation:missing value})
--> missing value
Therefore, for every place in your scripts where try...end try has been used to catch non-occurrences of properties inside a record data structure, simply delete the try blocks, and wherever you are assign values read from speculative property values, artificially insert default values you can then test for and will know whether or not the value came from your DEVONthink source or from your brain:
tell application id "DNtp"
repeat with g in (children of root of (think window 1))
set theAnnotation to annotation of (g & {annotation:false})
if theAnnotation ≠ false then exit repeat
end
end tell
1This isn't in any way meant to suggest his solution isn't viable. If DEVON returns collections that are not de-referenced--and it very well may do--these can be operated upon as a whole, without looping through individual items, and he, of course, uses DEVON. But the situation I hopefully address above is one that arises much more commonly, and will also work here.