PDA

View Full Version : Error Handling and why does this not work


ken.ferguson
2007-10-13, 05:49 PM
Not truely defined in the title there, but I have two different parts.

First issue: Am halfway decent in coming up with code on how to make something work, I totally suck at figuring out the errors. I've created a program that brings up a dialog box that allows a user to specify the options of a given block and then allows the user to insert it by clicking an "INSERT" button. I created a subroutine that will combine all of the options that the user selected and find the proper block to be inserted in the drawing. Once the user selects the point and rotation the dialog box pops back up showing the last set of options the user selected and allows them to continue making different choices. The program works fine but I run into two problems I can't solve:

1) If the user hits the ESC key the whole program crashes. I want the program to pick up back in the dialog box where I left off.

2) I want the user to have the option to place multiple blocks. Meaning instead of automatically bringing the dialog box back up after the rotation is set, allow the user to select another location until he/she hits the ESC key.


Second issue: I am using the insert command in my program which allows the user to place the blocks in the drawing. I tried using getpoint to store the location that the user selects but then I lose "dragging" when he/she specifies the rotation. Anyone run into this?


Thanks to all in advance!

CAB2k
2007-10-13, 06:45 PM
Post your code & someone will direct you as to what & where yo need to add code to catch the errors.

peter
2007-10-14, 02:10 PM
1) If the user hits the ESC key the whole program crashes. I want the program to pick up back in the dialog box where I left off.

The vlax-catch-all-apply function has the ability to trap an esc.

I use a standardized errortrap that I developed from a class I taught at Autodesk University a couple years ago. It uses the vlax-catch-all-apply function, but allows the user to pass functions to it, and will trap the error/esc in the function, and allow the routine to continue running.

for example

(defun C:Test ()
(errortrap (quote (alert "first alert box")))
(errortrap '(alert "second alert box"))
)

ken.ferguson
2007-10-15, 02:52 PM
This is one of the insertion routines for the program. This inserts plan view blocks and the other inserts 3D. Please see ";;" for trouble areas and specific notes.



(defun BlkIns_2D (dwgname mfcode pnum a2 a3 a4 a5)
(setq test2 dwgname)
(setq test pnum)


;; This is the area where I have a problem with the dragmode when I use getpoint.

(command "-insert" dwgname pause "" "" pause)

;; Peter: Would this be the place to catch the error? If so I am assuming that all
;; code that follows will have to be put in a cond/if statement.


(setq a (entget (entlast)))
(setq b (entget (entnext (cdr (assoc -1 a)))))
(setq bb (cdr (assoc 0 b)))

(if (= bb "ATTRIB")
(progn
(while (/= bb "SEQEND")
(setq bbb (cdr (assoc 2 b)))

; use AtribChange subroutine to change attribute values in blocks
(cond
((= bbb "PSPN") (AtribChange pnum))
((= bbb "PSMC") (AtribChange mfcode))
((= bbb "ITEXT") (AtribChange pnum))
((= bbb "ITEXT2") (AtribChange a2))
((= bbb "ITEXT3") (AtribChange a3))
((= bbb "ITEXT4") (AtribChange a4))
((= bbb "ITEXT5") (AtribChange a5))
)

(setq b (entget (entnext (cdr (assoc -1 b)))))
(setq bb (cdr (assoc 0 b)))
)
)
)

; update attribute values on blocks directly after insertion
(command "redraw")
)



Thanks again to all!

**Being self taught with sloppy habits I would love comments on the code as a whole. If anyone is interested let me know and I can email the code and support files.

CAB2k
2007-10-16, 02:08 AM
Try this out.
; Standardized Error Trap
; Written By: Peter Jamtgaard copr 2004
; This function will trap an error in an expression argument
; The syntax is (setq strLayer (errortrap '(vla-get-layer objSelection)))

(defun ErrorTrap (symFunction / objError result)
(if (vl-catch-all-error-p
(setq objError (vl-catch-all-apply
'(lambda (X)(set X (eval symFunction)))
(list 'result))))
(progn
(if DEBUG
(progn
(princ "\n")
(princ (vl-catch-all-error-message objError))
(princ "\nWhile evaluating the expression: ")
(princ symfunction)
(princ "\n")
)
)
nil
)
(if result result 'T)
)
)

(defun c:test()
(if (ErrorTrap '(command "-insert" dwgname pause "" "" pause))
(progn
... do you stuff if successful insert ...
)
(print "Error - Insert failed.")
)
(princ)
)

d_m_hopper
2007-12-10, 03:26 PM
do you mind checking this? If you need cond routines I will post them otherwise I will check on my own

;;;type rv to run

;;error trapping
(defun ErrorTrap (symFunction / objError result)
(if (vl-catch-all-error-p
(setq objError (vl-catch-all-apply
'(lambda (X)(set X (eval symFunction)))
(list 'result))))
(progn
(if DEBUG
(progn
(princ "\n")
(princ (vl-catch-all-error-message objError))
(princ "\nWhile evaluating the expression: ")
(princ symfunction)
(princ "\n")
)
)
nil
)
(if result result 'T)
)
)

(defun C:rv (/ inp )
;;; (setq clr (getvar "clayer"))

(if (errortrap '(initget "Pline Rectangle Circle") ; ask for input
(setq Inp (getkword "\nWhat type of cloud would you like to draw? [Pline/Rectangle/Circle] <Pline>: "))
(or Inp (setq Inp "Pline")))

(cond
((= inp "Pline")
(load "C:\\home\\GEHC\\pline_revcloud.lsp")
(C:pc)
)
((= inp "Rectangle")
(load "C:\\home\\GEHC\\rec_revcloud.lsp")
(C:RECRC)
)
((= inp "Circle")
(load "C:\\home\\GEHC\\circle_revcloud.lsp")
(C:cirrc)
)
)

(initget "1 2 3") ; ask for input
(setq Inp (getkword "\nWhich Revision is this? [1/2/3] <1>: "))
(or Inp (setq Inp "1"))
;; ==============
(rev inp)
;; ==============
(princ)
)

(defun rev (r# / sp bp ep COOR ID PAUSE TR TX txt CLR)

(setq sp (getpoint (strcat "Insertion point of Rev." r# " symbol: ")))
(setq bp sp)
(while
(not (equal ep bp))
(command "arc" sp pause pause)
(setq ep (getvar "lastpoint"))
(setq sp ep)
)



;; Triangle routine
(command "polygon" "3" bp "c" "5")
(setq tr (list (car bp) (+ (cadr bp) 10)))
(command "ortho" "off" "move" tr "" bp pause)

(setq tx (getvar "lastpoint"))
(command "color" "magenta" "text" "s" "dmt" "j" "m" tx "0" r# "color" "green")
(setq tr (list (car (getvar "lastpoint")) (+ (cadr (getvar "lastpoint")) 10)))

(cond
((= r# "1")
(setq coor '(1598.7021 -997.0960)
id '(1610.7021 -1002.0960)
)
)
((= r# "2")
(setq coor '(1598.7021 -1021.0960)
id '(1610.7021 -1026.0960)
)
)
((= r# "3")
(setq coor '(1598.7021 -1045.0960)
id '(1610.7021 -1050.0960)
)
)
)
(setq bp (list (- (car coor) 0.)(+ (cadr coor) 5.)))
(setq txt (list (car id)(- (cadr id) 12.)))



;;;============================================

;;; (if (= (tblsearch "layer" "border") nil)
;;; (command "-layer" "make" "border" "color" "3" "" "lt" "continuous" "" "")
;;; (command "-layer" "t" "border" "u" "border" "on" "border" "s" "border" "") )
(command "copy" "c" tx tr "" tx coor)




(command "text" "s" "dmt" "j" "bl" id 0
(getstring T "\nInitials and Date, (ex. ABC - 4/16/93): "))
(setq id(entlast))
(command "._change" id "" "P" "la" "border" "lt" "continuous" "lw" "0.0" "c" "green" "" )

;;;;fill in text


(command "text" "j" "bl" txt 0
(strcat "CHECKED BY: " (getstring T "\nEnter text (ex. JGA): ")))
(setq txt(entlast))
(command "._change" txt "" "P" "la" "border" "lt" "continuous" "lw" "0.0" "c" "green" "" )
(setvar "cmdecho" 1)
;;;(setvar "clayer" clr)
(print "Error - Routine exited.")
)

(princ)
)

ron_09812001
2007-12-11, 03:29 PM
hi to all, can i just ask what is the advantage/differences of using the vlisp error trap over the basic *error* user definable function?thanks

CAB2k
2007-12-11, 04:55 PM
Mr. Hooper,
You're not going to like what I have to say but I'm going to say it anyway.

You need to get the code working before you add the error handler. The error handler
is not the fix for improperly written code.

I know you are learning lisp & it can be frustrating at times. You need to learn the rules for
some of the basic functions & adhere to them.
Example:
The If function MUST be coded like this:
(if test_expression
then_expression
[else_expression] <---<< optional
)
When you need more than one function you need to wrap then in a progn like this:
(if test_expression
(progn
then_expression 1
then_expression 2
then_expression 3
) ; end of then_expression
[else_expression] <---<< optional
)

This structure is a must if you expect the routine to preform as expected.
Read this thread & believe me that once is not enough to learn it.
http://forums.augi.com/showthread.php?t=42122

In your posted routine look at this function:
(if (errortrap

Where does the then_expression start & stop and is there a else_expression?

Again, remove the error trap for now, YOU want the routine to crash until only 'user caused errors'
exist. Then add the error trap. By crashing the routine you can see what to fix in the code to prevent it.
I assume you are using VLIDE to write & test the code, if not you should.

Ok, Looking at the first bit of code to get user choice.
(initget "Pline Rectangle Circle") ; ask for input
(setq Inp
(getkword
(strcat "\nWhat type of cloud would you like to draw? "
"[Pline/Rectangle/Circle] <Pline>: "))
)
(or Inp (setq Inp "Pline"))
As you have taken care of the null response i.e. Enter key only, with a default to Pline, looks like the
only error could be the user pressing the escape key. Then you must decide what you want to do as
a programer. If you have changed some system variables that need to be restored you will want to trap
this attempt from the user to abort and restore the variables before exiting.
If you want the user prevented from exiting the routine you can trap the error & force the user to continue
or optionally allow the user to exit.

I'll show you how to do this but first lets get this routine working without these options.

Next you have some code to process the user choice.
From the input above there are only three choices & nothing else can happen except ESCAPE and the escape
we will deal with later.
So in the three options you have a line of code that happens every time. Well there is no decision needed
before executing that line of code so it does not need to be in the conditional function.
Here is the revised code:
(load "C:\\home\\GEHC\\pline_revcloud.lsp") ; happens every tine
;; based on the user choice run one of these routines
(cond
((= inp "Pline")
(C:pc)
)
((= inp "Rectangle")
(C:RECRC)
)
((= inp "Circle")
(C:cirrc)
)
)

Looks ok but you turned control over to another lisp and you did not get a return argument.
It may have it's own error handler and it may have created objects you want to use.
There are several options to consider here.
1- there was an error and the entire routine was terminated
2- there was an error and it was trapped. How do you know & how do you want to deal with it?
3- objects were created that you want to work with
-- How do you know what happed & how do you get the new object information?
If the routine was terminated you are left with system variables that are not restored.
If the error was trapped or objects created you need to know some how.
A return argument is the best way. It may be null if an error was trapped. This way you can terminate your
routine or loop to try again. If the return value is data like a list of Entity names of objects created or a point
coordinate you could use that to add your text.

Another method would be to get the last object in the drawing database before calling the routine and then
getting any new objects added after the last one you found. this would tell you that the routine was at least
partially successful & give you Entities to work with.

Another way is with Global variables. The called routine would set these & after you called the routine yo could
test there variables to see what happened.

When writing lisp routines it is good practice to limit the use of global variable. Use a return argument when
ever possible. If you have more that one variable to return just create a list of the variables & return that list.


Well I've rambled long enough & need to get some work done here.

If you will revise your routine I or someone here will help you through the process. Please leave out the error trap
for now and could you post this in a new thread. If you don't mind start with some pseudo code, just a list of things
you want the routine to do and in the order they need to happen.

CAB2k
2007-12-11, 05:18 PM
PS While you are studying you may want to look at this example of a method to error trap a command.
http://www.theswamp.org/index.php?topic=20353.0

d_m_hopper
2007-12-11, 08:35 PM
PS While you are studying you may want to look at this example of a method to error trap a command.
http://www.theswamp.org/index.php?topic=20353.0

you now what, thanks...I need explanations like that to learn.

I will read this at home tonight and 'fix' it, thanks for the tips and advice

Also I do use vlide to write code