Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Custom Error Handeling

12 REPLIES 12
Reply
Message 1 of 13
michael
1382 Views, 12 Replies

Custom Error Handeling

I had a two lisp programs that I've been running for a few years with no problems until now.  I had several different commands for applying different hatch paterns, line types, and blocks to my drawings.  I didn't have an error handaler that realy ever handled what I wanted it to handel.  I did have a system that would capture my settings and once the program was done runing it would reset them.  Now it has lost the ability to reset my settings and I believe it has something to do with the clayer code?  I am not a coder and am trying to teach myself from the comunity here and the forums so even if you could point me in the right direction to learn this it would be greatly apreciated.

 

My first code is called error.lsp and has the following code:

 

(defun error ()
  (prompt "\nGlobal Error Trap Loaded")
  (princ)
  ); defun
;;;*=========================================
(defun initerr (/ oldlayer oldsnap oldpick temperr)
  (setq oldlayer (getvar "clayer"))
  (setq oldsnap (getvar "osmode"))
  (setq oldpick (getvar "pickbox"))
  (setq temperr *error*)
  (setq *error* trap)
  (princ)
  );defun
;;;*=========================================
(defun trap (errmsg)
  (command nil nil nil)
  (if (not (member errmsg '("console break" "Function Cancelled"))
	   )
    (princ (strcat "\nError: " errmsg))
		   )

  (command "undo" "b")
  (setvar "clayer" oldlayer)
  (setvar "menuecho" 0)
  (setvar "highlight" 1)
  (setvar "osmode" oldsnap)
  (setvar "pickbox" oldpick)
  (princ "\nError Resetting Enviroment ")
  (terpri)
  (setq *error* temperr)
  (princ)
  );defun
;;;*===============================================
(defun reset ()
  (setq *error* temperr)
  (setvar "clayer" oldlayer)
  (setvar "menuecho" 0)
  (setvar "highlight" 1)
  (setvar "osmode" oldsnap)
  (setvar "pickbox" oldpick)
  (princ)
  );defun
;;;*===============================================
(princ)

(vl-load-com) (princ)
(princ "\n:: Error loaded sucesfully ::")
(princ)

 

The second code is called Blocks.lsp and this is just a cut of one code inside it.

 

(defun c:Existing (/ la old_cmdecho)
  (command initerr)
  (setvar "cmdecho" 0)
  (command "undo" "m")
  (setvar 'hpname "ansi36")
  (setvar 'hpscale 15)
  (command "-layer" "S" "screening" "")
  (command "-hatch")
  (while (> (getvar 'cmdactive) 0) (command pause))
  (command reset)
  (princ)
)

 

When I run the second code it tells me: "; error: bad argument value: AutoCAD command: #<USUBR @0000000041d5d660 INITERR>"

 

Now if I go change my code to be "defun c:*", star being each line of code in the first code that requires it,  I get the following: "Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended."

 

If I run initerr alone it appears to run but if I change my layers to a different type and run reset it says: "; error: AutoCAD variable setting rejected: "clayer" nil"

 

for whatever reason this worked in AutoCAD2014 but now doesn't in 2015.  I've tried to find a fix but I don't understand some of the error code that is written out there.  Also I'd like to have the procedure called into each individual code so I don't have to write a length addition to all of the abbreviations I have.

Tags (3)
12 REPLIES 12
Message 2 of 13
Kent1Cooper
in reply to: michael

Try it using not

(command initerr)

but rather just

(initerr)

 

AutoCAD 2015 no long allows (command) functions inside *error* functions, unless you go through the rigmarole it mentions.  I have taken to using the (vla-) approach for its equivalent to Undo End, if that's the only thing I would be using (command) for in *error*, but I don't think that can do an equivalent of Undo's Back option, so the easiest solution is probably to just change (command ... to (command-s within the *error* handler.

Kent Cooper, AIA
Message 3 of 13
michael
in reply to: Kent1Cooper

That got me back to working but the layers still don't revert back to the origional settings.  For example if I select a hatch lisp when I'm on my object layer it will switch to the hatch layer, select the hatch with appropriate scale, and then wait for me to pick.  If I pick a point and end the program it will stay on the Hatch pattern instead of changing back to the object layer.  Same thing will happen with a block insert excpet it will not reset my osnaps.  I think it gets caught on the clayer step and then canels the program?

Message 4 of 13
Kent1Cooper
in reply to: michael

I didn't notice this one the first time.  Similarly to the usage of (initerr), use just

(reset)

instead of

(command reset)

 

The (command) function recognizes only AutoCAD's own command names, not the names of (defun ...) functions, and not even (defun C:...) custom command definitions.

Kent Cooper, AIA
Message 5 of 13
scot-65
in reply to: michael

>>but the layers still don't revert back to the origional settings
Another method to consider, which I employ whenever possible, is to allow AutoCAD to create the object while in the undisturbed environment, THEN, once it is created, direct to the appropriate environment (using entnext, entlast, etc.).
This way an error handler *might* not be necessary.

Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 6 of 13
michael
in reply to: Kent1Cooper

Okay so I think I got my code straightened out with the changes.  Here is the new line of code:

 

(defun c:Existing (/ la old_cmdecho)
  (initerr)
  (setvar "cmdecho" 0)
  (command "undo" "m")
  (setvar 'hpname "ansi36")
  (setvar 'hpscale 15)
  (command "-layer" "S" "screening" "")
  (command "-hatch")
  (while (> (getvar 'cmdactive) 0) (command pause))
  (reset)
  (princ)
)

 

(defun error ()
  (prompt "\nGlobal Error Trap Loaded")
  (princ)
  ); defun
;;;*=========================================
(defun initerr (/ oldlayer oldsnap oldpick temperr)
  ;(setq oldlayer (getvar "clayer"))
  (setq oldsnap (getvar "osmode"))
  (setq oldpick (getvar "pickbox"))
  (setq temperr *error*)
  (setq *error* trap)
  (princ)
  );defun
;;;*=========================================
(defun trap (errmsg)
  (command nil nil nil)
  (if (not (member errmsg '("console break" "Function Cancelled"))
	   )
    (princ (strcat "\nError: " errmsg))
		   )

  (command "undo" "b")
  (setvar "clayer" oldlayer)
  (setvar "menuecho" 0)
  (setvar "highlight" 1)
  (setvar "osmode" oldsnap)
  (setvar "pickbox" oldpick)
  (princ "\nError Resetting Enviroment ")
  (terpri)
  (setq *error* temperr)
  (princ)
  );defun
;;;*===============================================
(defun reset ()
  (setq *error* temperr)
  (setvar "clayer" oldlayer)
  (setvar "menuecho" 0)
  (setvar "highlight" 1)
  (setvar "osmode" oldsnap)
  (setvar "pickbox" oldpick)
  (princ)
  );defun
;;;*===============================================
(princ)

(vl-load-com) (princ)
(princ "\n:: Error loaded sucesfully ::")
(princ)

 But I'm still getting the following: "Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended."

This cancels the command without reverting back to origional settings.  I'm guessing it is something in my reset?

 

I have found a few articles on the (*push-error-using-command*) and I've tried to adjust my error handaling code to accomidate it but I really must not have a grasp on what they are doing?  It kind of appears that they are just undoing all the changes if an error occurs and doesn't handle any type of reset at the end.

 

Thanks for all your help and I'll keep digging for a solution.

 

Message 7 of 13
hmsilva
in reply to: michael

This >>>*push-error-using-stack* (AutoLISP)<<< may be useful

 

Henrique

EESignature

Message 8 of 13
Kent1Cooper
in reply to: michael


@Anonymous wrote:

.... 

....
(defun trap (errmsg) (command nil nil nil) .... (command "undo" "b") ....
);defun ....

 But I'm still getting the following: "Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended."

....


You still have (command ...) functions in the (trap) that should be changed to (command-s ...).

Kent Cooper, AIA
Message 9 of 13
michael
in reply to: Kent1Cooper

I've tried all these suggestions and I keep getting my behind kicked!  I tried to break it down to what works and billed it back up from there.  I took the initerr and the reset code and put them directly into my main lisp routine.  I then took out the error stuff so that it would only change my settings and the revert them back to the originals so that at least I could run the lisp and get the results I wanted.  If I esc. out of it then I'd have to go reset all my settings but that was better then having to reset them every time I ran the program anyway.  So now that I did that it still hangs on the (setvar "clayer" oldlayer) and returns "; error: AutoCAD variable setting rejected: "clayer" nil"?  Now I'm supposed to be getting my clayer in the initerr command but it doesn't seam like it's either not getting it or not holding it?  Any thoughts?  If I break this down and put all the variables I want changed and reset into each individual lisp routine then it works (at least in the single one I tried).  I don't really want to repeat all that code over and over if I can avoid it! 

Message 10 of 13
michael
in reply to: michael

Okay ignore all of this! I caught that I was using the local variables in the initerr command so they were forgot after it ran! Now it's working but without the error catching. I put all of it back in and changed the two command to command-s as Kent1Cooper explained. It returns "Application ERROR: Invalid type sent as command input" and prompt says "Unkown (comand-s) failure.
Message 11 of 13
hmsilva
in reply to: michael

Hi Michael,
Probably (I don't have 2015 for test) the 'Unkown (comand-s) failure.' is the return from (command-s nil nil nil), the use of nil in the command call was to cancel any pending command (the same as press 'esc' three times), the command-s function with a 'nil' will throw an error because it's not a AutoCAD command.
Try replacing the (command-s nil nil nil) for (repeat 3 (command-s))

 

I hope this helps
Henrique

EESignature

Message 12 of 13
michael
in reply to: hmsilva

Today I go on vacation for the next week!  I am so happy to say that this lisp routine now runs correctly!  I would like to mark all your responses as answers but there were so many problems I had throught this ordeal that I'm not sure anyone else would beable to follow it!  Thank you ALL for the responses and thank you hmsilva I had not seen this solution anywhere else and that is what I need to fix the error problem.

Message 13 of 13
hmsilva
in reply to: michael

You're welcome, Michael.
Glad you got a solution!
Enjoy your vacation!

Henrique

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost