PDA

View Full Version : Error Handling:



spencer.67965
2004-09-14, 03:18 PM
Hello All,

Just wondering if there is any error handling in AutoLISP; if so could someone give me an example. I am trying to exit gracefully during a routine when I press the "ESC" Button.

Thanks,

Spencer
___________________
AutoCAD 2005

kennet.sjoberg
2004-09-14, 04:21 PM
Hi Spencer ! This is my offer . .

(defun c:MyProg (argument / localvariable OldOsm ) ;; *globalvariable*

; Errorhandler
(defun MyProg_Err ( msg )
(princ (strcat "User [Esc]. " msg ) )
(setvar "OSMODE" OldOsm ) ; and many more "take care of"
(setq *error* OldErr )
(command "_.UNDO" "End")
;(command "_.U") ; sometimes
)

;;; Program Start
(command "_.UNDO" "BEgin")
(setq OldErr *error* *error* MyProg_Err )
(setq OldOsm (getvar "OSMODE" ) ; and many more "take care of"
; all your program code

;;; Program End
(command "_.UNDO" "End")
(setvar "OSMODE" OldOsm ) ; and many more "take care of"
(setq *error* OldErr )
(princ)
)

Happy Computing !

kennet

RobertB
2004-09-14, 11:41 PM
Spencer,

Kennet's reply might be a bit confusing. Let me try with a bit more information.

*Error* is the traditional error handler for Auto/Visual LISP. Beginning with AutoCAD 2000, the error handler could be declared as a local variable and remain local even when it ran. The (setq OleErr ...) stuff Kennet did is rather old-school, only needed if you must support older versions of AutoCAD (but I digress).

The error handler can be both global and local. If you do this:
Command: (defun *error* (msg) (princ "[Global] error: ") (princ msg) (princ))
You have essentially recreated the default global error handler, with the addition of the "[Global]".
So, Command: (/ 1 0)
[Global] error: divide by zero

Now, to define a local error handler, you simply need to declare it a local in the parent function, and define it inside the parent function.

(defun C:Test (/ *Error*)
(defun *Error* (msg) (princ "[Local] error: ") (princ msg) (princ))
(/ 1 (getint "\nDivide 1 by: ")))
This code does this when run at the command line:
Command: test
Divide 1 by: 1
1

Command: test
Divide 1 by: 0
[Local] error: divide by zero

Note that if you trigger an error at the command prompt itself the global error handler still runs.
Command: (/ 1 0)
[Global] error: divide by zero

So, now that you see how to make a local error handler, let's add a trap for cancelling the function.

(defun C:Test (/ *Error*)
(defun *Error* (msg)
(cond ((not msg)) ; normal exit
((member msg '("Function cancelled" "quit / exit abort"))) ; <Esc>
((princ (strcat "\n[Local] error: " msg)) ; display fatal error
(cond (*Debug* (vl-bt))))) ; if in debug mode, dump backtrace
(princ))
(/ 1 (getint "\nDivide 1 by: ")))
Command: test
Divide 1 by: *Cancel*

Command: test
Divide 1 by: 0
[Local] error: divide by zero

I hope this further clairified things! (I'll leave it up to you to figure out how the debug mode works, but I bet you'll like it!)

spencer.67965
2004-09-15, 01:48 PM
Thanks for clarifying that for me. I'll give it a go and see if I have any other question.

Spencer

kennet.sjoberg
2004-09-15, 09:18 PM
Hi again Spencer !

In my offer I take care of user variables, when a user use a program the program must leave the user environment unchanged when the program is done, even if the program crash or the user hit the [Esc] key.
And it also step back to the starting point if something goes wrong.
And if you create many objects with the program it removes them all if you after the program change your mind and type the "Command _U"

To do
1. (defun c:MyProg ( / ) ;; MyProg_Err

or

2. (defun c:MyProg ( / MyProg_Err )
is a up to you

Number 1. has a global error handler and is compatible with R14 and earlier versions
you can call that error handler in other similar program that you make.

Number 2. has a internal error handler and is not compatible with R14 and earlier versions
but save a little bit RAM memory if you have a low low level computer,
but You can not call that one from other program.

The error handler itself can be written to just take care, or be unnecessary excessive
you set the level.

Happy Computing !

kennet