Bulletproof AutoLISP *error* Handlers, System Variable Stacks & Undo Group Hygiene (dev-cookbook-28)
Prevent corrupted OSMODE, CMDECHO, and CLAYER settings when users press ESC in GstarCAD 2027 AutoLISP routines using lexical *error* traps and vla-StartUndoMark.
1. Why Unprotected AutoLISP Routines Corrupt User Workspaces on `ESC`
Nothing frustrates a production drafting team faster than pressing `ESC` mid-command to cancel an in-house AutoLISP tool and discovering that their Object Snaps (`OSMODE`) have been wiped to `0`, file dialogs (`FILEDIA`) are disabled, the active layer (`CLAYER`) is stuck on a construction layer, and pressing `Ctrl+Z` (`UNDO`) requires 45 separate keystrokes to roll back partial geometry. In GstarCAD 2027, every enterprise AutoLISP command must wrap its execution body inside a deterministic **System Variable Stack + Local `*error*` Trap + ActiveX Undo Group**.
2. The Gold-Standard GstarCAD 2027 AutoLISP Command Template
By declaring `*error*` as a local symbol inside the `defun` parameter list `(defun C:MYCMD ( / *error* sysVars ...))`, LISP dynamically binds your custom error trap for the duration of the command and automatically restores the global `*error*` handler when the function exits—whether normally or via an exception/cancel signal:
;; EnterpriseAutoLispTemplate.lsp - Transactional SysVar Stack & Undo Group Wrapper
(vl-load-com)
(defun C:GC_SAFE_ROUTE ( / *error* doc savedVars SetSysVars RestoreSysVars pt1 pt2)
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
;; 1. Helper: Snapshot and apply a list of '(("VARNAME" . newValue) ...) pairs
(defun SetSysVars (varPairs)
(setq savedVars
(mapcar
'(lambda (pair)
(cons (car pair) (getvar (car pair)))
)
varPairs
)
)
(foreach pair varPairs
(setvar (car pair) (cdr pair))
)
)
;; 2. Helper: Deterministically restore all snapshotted system variables
(defun RestoreSysVars ()
(if savedVars
(progn
(foreach pair savedVars
(vl-catch-all-apply 'setvar (list (car pair) (cdr pair)))
)
(setq savedVars nil)
)
)
)
;; 3. Local lexical *error* trap invoked on ESC, Cancel, or runtime exception
(defun *error* (msg)
(RestoreSysVars)
(vla-EndUndoMark doc)
(if (and msg
(not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*,*QUIT*")))
(princ (strcat "
[GC_SAFE_ROUTE Error]: " msg))
)
(princ)
)
;; 4. Begin Atomic Undo Group & Apply Temporary Command Environment
(vla-StartUndoMark doc)
(SetSysVars
'(("CMDECHO" . 0)
("OSMODE" . 0)
("ORTHOMODE". 1)
("BLIPMODE" . 0))
)
;; 5. Core Interactive Command Logic (Safe even if user hits ESC here!)
(if (and (setq pt1 (getpoint "
Specify duct start point: "))
(setq pt2 (getpoint pt1 "
Specify duct end point: ")))
(progn
(entmakex
(list '(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(8 . "M-DUCT-MAIN")
'(100 . "AcDbPolyline")
'(90 . 2)
'(43 . 2.5)
(cons 10 pt1)
(cons 10 pt2)))
(princ "
Routed primary duct segment successfully.")
)
)
;; 6. Clean Normal Exit Path
(RestoreSysVars)
(vla-EndUndoMark doc)
(princ)
)
3. Why `vla-StartUndoMark` Is Superior to `(command "_.UNDO" "_Begin")`
In legacy AutoLISP code, developers often invoked `(command "_.UNDO" "_Begin")` and `(command "_.UNDO" "_End")`. However, invoking `(command ...)` inside an `*error*` handler when the user has just pressed `ESC` during an active prompt can fail or trigger nested command-state warnings. Calling **`(vla-StartUndoMark doc)`** and **`(vla-EndUndoMark doc)`** bypasses the command-line parser completely and writes the undo boundary directly into GstarCAD 2027's C++ database transaction stream, guaranteeing that a single `Ctrl+Z` cleanly reverses the entire routine.
4. Auditing Global Namespace Pollution (`atoms-family`) in Shared `.LSP` Libraries
A subtle bug in multi-developer AutoLISP repositories occurs when helper scripts forget to declare loop counters (`i`, `ent`, `pt`, `ss`) after the `/` slash in `(defun MyHelper (arg1 / i ent pt ss) ...)`. Unlocalized symbols leak into the global document namespace and can overwrite variables in calling functions. Run a pre-commit LISP check comparing `(atoms-family 1)` before and after executing your command to verify zero unintended global symbol leakage.
Validate This Workflow in GstarCAD 2027
Engineered by Suzhou Gstarsoft Co., Ltd. (SSE: 688657), GstarCAD 2027 delivers 100% native AC1032 DWG binary fidelity, perpetual licensing sovereignty, and zero-day AutoCAD command parity.