Caution around
(handent …) Function
If not used carefully, this
function can easily generate “bad argument type: stringp nil” or “bad argument
type: lentityp nil” errors in our product. The purpose of this function is to
convert a hexadecimal text string value that represents an object “handle” ID
into an entity name assignment. AutoCAD uses this entity name to access the
target object in the drawing. This ascii text string is the function’s only
argument.
The most serious problem
occurs immediately if the passed string value is nil. Our program will exit
with a “bad argument type: stringp nil” error.
A real-world example: here is a
line of code that triggered a recent regression ():
(setq layername (cdr (assoc 8 (entget (handent entname)))))
In this example, the variable
“netwire” could, under certain conditions, be passed as a value of nil instead
of as an ASCII text string giving the handle number. The function (handent
netwire) that is embedded in the line of code above fails with the error
message “bad argument type: lentityp nil”. You can simulate this at the command
line. Type in this sequence: (setq netwire nil) [Enter] and then (handent
netwire) [Enter].
The above line of code has a second
potential problem. Even if “netwire” is not nil but is an ASCII text
string, it might not convert to a valid entity name in the active drawing. In
this case, the (handent…) function will not fail but will simply return nil.
But, this creates a downstream problem. The nil value gets passed to the
(entget…) function. When passed a nil value instead of a valid entity name, the
(entget…) function fails. The program stops with the error “bad argument: lentityp nil”. You can simulate this at the command line by typing
this: (entget (handent “ABCD1234”)) [Enter]
How to Use (handent …) Safely
In the above example, two checks are needed. First check is
to make sure that “netwire” is not a nil value. The second is that “netwire” is
a valid handle ID for an entity in the target drawing. So, these two checks
might be coded up like this:
(if (AND entname(handent entname)
(entget (handent entname))) (setq layername (cdr (assoc 8 (entget (handent entname))))))
… or, a written a bit more efficiently…
(if (AND entname(setq en (handent entname)) (entget en))
(setq layername (cdr (assoc 8 (entget en)))))