Is there a need to cancel active commands in custom *error*?

Is there a need to cancel active commands in custom *error*?

tditullio
Participant Participant
1,229 Views
4 Replies
Message 1 of 5

Is there a need to cancel active commands in custom *error*?

tditullio
Participant
Participant

I just upgraded to 2016 from 2012.

In prior versions up thru 2012 I had this line in my standard custom *error* function to cancel any active commands that was used by most of my apps.

 

(while (> (getvar "CMDACTIVE") 0)(command))

 

Now with 2016 I need to use the (command-s ...) function in the *error* but calling just (command-s) without any arguments does not cancel active command the way (command) did from what I have read and tested.

 

How do you handle canceling any active commands in 2015+? Or is it even need anymore?

 

By the testing I have done, it seems that any active command is canceled on error anyway. But I have not test every possible case. The main reason in the past for canceling active commands was I would do an "undo" "begin" when app started and an "undo" "end" when exiting or on error (along with resetting other misc things) that I think would fail if another command was active (it's been awhile so I forget now).

 

Below is the standard functions used by most of my code for reference. The line above in question is currently commented out as it fails.

 

;;;* * * * * * * * * * * * * ERROR FUNCTIONS * * * * * * * * * * * * * * *
;;;
;;; hgc_error
;;;
;;; General *ERROR* Handling function
;;; usage - (setq *error* hgc_error)

(defun hgc_error (msg)                 ;standard error function
  (hgc_reset_system)
)

 

;;;=======================================================================
;;;
;;; hgc_save_system
;;;
;;; Save existing drawing editor settings
;;; use as first function in program
;;; after called, make setvar changes and set *error* to hgc_error

(defun hgc_save_system ()              ;saved existing system settings
  (setq hgc_saved_err  *error*
        hgc_highlight (getvar "HIGHLIGHT")
        hgc_osmode    (getvar "OSMODE")
        hgc_orthomode (getvar "ORTHOMODE")
        hgc_autosnap  (getvar "AUTOSNAP")
        hgc_aperture  (getvar "APERTURE")
        hgc_dimzin    (getvar "DIMZIN")
        hgc_textstyle (getvar "TEXTSTYLE")
        hgc_expert    (getvar "EXPERT")
        hgc_cmdecho   (getvar "CMDECHO")
  ) ;setq
  (setvar "CMDECHO" 0)
  (command-s ".UNDO" "BEGIN")             ;05-16-16 Changed to command-s
  (setvar "CMDECHO" hgc_cmdecho)
)

;;;=======================================================================
;;;
;;; hgc_reset_system
;;;
;;; Resets drawing editor settings
;;; use at end of program

(defun hgc_reset_system ()             ;reset existing system settings
  (setq    *error*    hgc_saved_err)
  ;(while (> (getvar "CMDACTIVE") 0)(command))   ;cancel any active commands **********CODE IN QUESTION************
  (setvar "textstyle" hgc_textstyle)
  (setvar "HIGHLIGHT" hgc_highlight)
  (setvar "OSMODE"    hgc_osmode)
  (setvar "ORTHOMODE" hgc_orthomode)
  (setvar "AUTOSNAP"  hgc_autosnap)
  (setvar "APERTURE"  hgc_aperture)
  (setvar "DIMZIN"    hgc_dimzin)
  (setvar "EXPERT"    hgc_expert)
  (command-s ".UNDO" "END")                        ;05-16-16 Changed to command-s
  (setvar "CMDECHO"   hgc_cmdecho)
  (prin1)
)

1,230 Views
4 Replies
Replies (4)
Message 2 of 5

john.uhden
Mentor
Mentor
I'm still using 2002, but I don't think you need to cancel any commands in your *error* function. Your code would not have arrived there unless something went wrong or you call *error* at the end of your main function, by which time any command would have been completed.

John F. Uhden

0 Likes
Message 3 of 5

JamesMaeding
Advisor
Advisor

I've never done that, and never found a need so far.

I don't even know how to make a command continue if a lisp running inside it gets to the error function.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 4 of 5

dbroad
Mentor
Mentor

Interesting question.  I complained loudly when Autodesk made this change for this exact reason.  There seemed to be no way to cancel pending commands.  There is, however, a quirky workaround.  See this page:

https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-AutoLISP/file...

 

Now here are the real sticky points when using *push-error-using-command*:

1)The error handler cannot be defined locally.  It must be global.

2)The variables to save the old error handler must be global because,

3)Any variables to use in the command version of the error handler must be global.

 

This, for example, will work:

(defun myerr (msg)
  (princ "\nMy error handler: ")
  (princ "\n")
  (while (> (getvar "cmdactive") 0)
    (command)
    )
  (princ msg)
  
  )

(defun c:test ( )
  (setq olderr *error*
	*error* myerr) 
  (*push-error-using-command*)
  (command "line" "0,0")
  (/ 1 0)
  (setq *error* olderr)
  (*pop-error-mode*)
  )

This, however, will not work:

Spoiler

(defun c:test ( / *error*)
(defun *error* (msg)
(princ "\nMy error handler: ")
(princ "\n")
(while (> (getvar "cmdactive") 0)
(command)
)
(princ msg)

)

(*push-error-using-command*)
(command "line" "0,0")
(/ 1 0)
(setq *error* olderr)
(*pop-error-mode*)
)
Architect, Registered NC, VA, SC, & GA.
Message 5 of 5

john.uhden
Mentor
Mentor
Sheesh. That's reminiscent of R12 or earlier. You should still be complaining.

John F. Uhden

0 Likes