Author Topic: Error Traps  (Read 5974 times)

0 Members and 1 Guest are viewing this topic.

daron

  • Guest
Error Traps
« on: October 26, 2004, 09:05:34 AM »
I would like some help in understanding error trapping and the like. I've writte this procedure for a job I'm doing and I don't want to send it out able to break. What I'd like is for someone to, if it's possible, show me where to put in something like vl-catch- and vl-exit-with functions and then make this thing error out properly. As you can see in the t statement in the code, it says it's going to reset variables. I have nothing to do that with.

Code: [Select]
;;;-------------------------pseudo-code-----------------------------------;
;;;-Take a selection set (any number of ssget objects) and parse through  ;
;;; them converting each object to a vla-object and appending them in a   ;
;;; list. Then, deleting the entity from the selection set, until the loop;
;;; returns nil. Make sure the selection set is of type pickset  ;
;;;-------------------------ss-vla-list-----------------------------------;
;;;-Takes any selection set and coverts it into a list of AX objects      ;
;;;-Arguments: selection set  ;
;;;-Example: (ss-vla-list ss)  ;
;;;-----------------------------------------------------------------------;
;;; Author: Daron Rogers  ;
;;; Date: October 22, 2004 10:32PM  ;
;;;_______________________________________________________________________;
(defun ss-vla-list (selset / ename ax-list)
 ;define function (arguments / local vars)
     (cond
 ((= (type selset) 'PICKSET)
 ;ensures the argument selset is usable by the ssname function
  (while (setq ename (ssname selset 0))
 ;while there are entity names in selset
(setq ax-list
 (append
      ax-list
 ;append each item in the list to each other
      (list (vlax-ename->vla-object ename))
 ;after converting them to ActiveX objects
 )
)
(ssdel (ssname selset 0) selset)
 ;ssdel will take selset and remove the first item in the list
  )
 )
 (t
  (princ
"\nArgument passed to this function was not of TYPE, PICKSET.\nResetting variables."
  )
  (setq ax-list nil)
 )
     )
 ;while continues until ename variable equals nil
     ax-list
 ;ax-list is the return value. If it weren't there ss-vla-list would
 ;return nil and any program accessing it would error out.
)


P.S. I just remembered another thing. Can someone show me how to properly use entdel. I was trying to use it yesterday and although it deleted the object, it would error out, thus making further calls not work.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Error Traps
« Reply #1 on: October 26, 2004, 09:17:31 AM »
Since you have localized your variables, there should be none to reset UNLESS someone cancels the lisp in the middle of it's execution. If that is the case, you will need to define an error handler to do it for you...but it will not return control to the calling module automatically....

Code: [Select]

(defun *error* (err)
 (if (= err "Function cancelled")
  ;do this stuff
 )
)
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #2 on: October 26, 2004, 09:34:15 AM »
This should take care of the entdel
(ssdel ename selset)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #3 on: October 26, 2004, 09:48:19 AM »
I did not see the need for a local error trap, looks like you have it covered.
If the user hits Escape they are exiting the entire routine and the
main error handler should reset the system.
Nice routine Daron.
Code: [Select]
;;;-------------------------pseudo-code-----------------------------------;
;;;-Take a selection set (any number of ssget objects) and parse through  ;
;;; them converting each object to a vla-object and appending them in a   ;
;;; list. Then, deleting the entity from the selection set, until the loop;
;;; returns nil. Make sure the selection set is of type pickset        ;
;;;-------------------------ss-vla-list-----------------------------------;
;;;-Takes any selection set and coverts it into a list of AX objects      ;
;;;-Arguments: selection set                    ;
;;;-Example: (ss-vla-list ss)                    ;
;;;-Returns list of vla ovjects or nil if ss is empty or not a selection set
;;;-----------------------------------------------------------------------;
;;; Author: Daron Rogers                    ;
;;; Date: October 22, 2004 10:32PM                 ;
;;;_______________________________________________________________________;
(defun ss-vla-list (selset / ename ax-list)
  ;;define function (arguments / local vars)
  (cond
    ((= (type selset) 'pickset)
     ;;ensures the argument selset is usable by the ssname function
     (while (setq ename (ssname selset 0))
       ;;while there are entity names in selset
       (setq ax-list
              (append
                ax-list
                ;;append each item in the list to each other
                (list (vlax-ename->vla-object ename))
                ;;after converting them to ActiveX objects
              )
       )
       (ssdel ename selset)
       ;;ssdel will take selset and remove the first item in the list
     )
    )
    (t
     (princ
       "\nArgument passed to this function was not of TYPE, PICKSET.\nResetting variables."
     )
     ;;(setq ax-list nil)
     ;;  because ax-list is a local var it will be nil if we get here
    )
  );while continues until ename variable equals nil
  ax-list
  ;;ax-list is the return value. If it weren't there ss-vla-list would
  ;;return nil and any program accessing it would error out.
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #4 on: October 26, 2004, 10:05:11 AM »
Here is one I ran across but I did not get the authors name.
Code: [Select]
;;; given a selection set this function will convert it
;;; to an assocation list of vla-objects and layer names
;;; i.e. ((#<VLA-OBJECT IAcadLine 0d0b5fa4> . "BASELINE"))
;;; remove any vla-objects from the list that are on a
;;; locked layer and return the final list
;;;
;;; usage
;;; (setq ss (ssget))
;;; (setq lst (remove-if-locked ss))
(defun remove-if-locked (ss / *activedoc* layersobj parse-ss
                            obj-layer obj-lst rem-locked
                            chg-obj-layer lst-done)

  ;; intialize ActiveX
  (vl-load-com)

  ;; create a list of vla-objects from the selection set
  (defun parse-ss (ss / cntr ent obj-lst)
    (setq cntr 0)
    (while
      (setq ent (ssname ss cntr))
      (setq obj-lst
            (cons (vlax-ename->vla-object ent) obj-lst)
            cntr (1+ cntr)
            )
      ); while
    (obj-layer obj-lst); call obj-layer
    ); defun

  ;; generates an association list of object and layer name
  (defun obj-layer (lst / objlayr)
    (foreach obj lst
             (setq objlayr
                   (cons (cons obj (vla-get-Layer obj)) objlayr)
                   )
             )
    (rem-locked objlayr); call rem-locked
    ); defun

  ;; remove objects on locked layers
  (defun rem-locked (lst)
    (setq lst-done
          (vl-remove-if
            '(lambda (l)
               (= (vla-get-lock (vla-item layersobj (cdr l))) :vlax-true)
               )
            lst
            )
          )
    ; the final list of (<vla-objects> .  "layer names")
    lst-done
    ); defun

  ;; make sure we have a selection set
  (if
    (= (type ss) 'PICKSET)
    (progn
      (setq *activedoc* (vla-get-ActiveDocument (vlax-get-acad-object))
            layersobj (vlax-get-property *activedoc* 'Layers)
            )
      ;; call parse-ss
      (parse-ss ss)
      )
    ); if

  ); defun
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #5 on: October 26, 2004, 12:33:57 PM »
This thread has not answered darons question as to how the errors can be trapped.
I have not used the vl-catch function yet so I am curious too.
How would it be implemented in the code below?
If you select say a circle with a diameter of 60 units the offset to the inside causes
an error.

Code: [Select]
;;  Double Offset Method - CAB  02/17/2004
;;  offset to both sides a given distance
;;  Arguments
;;    ename is an entity name
;;    dist is the offset distance
;;  Returns
;;   nil if failed or
;;   list of the two new entities
;;
(defun OffsetDouble (ename dist / vobj enew)
  (setq vobj (vlax-ename->vla-object ename))
  (if (vlax-method-applicable-p vobj 'Offset)
    (progn
      (vlax-invoke vobj 'Offset dist)
      (setq enew (entlast))
      (vlax-invoke vobj 'Offset (- dist))
      (setq enew (list (entlast) enew))
    )
    (prompt "\nCannot offset selected object type.")
  )
); defun

;;  double offset helper
;;  preset offset distance
(defun c:dblo25(/ ent ofd)
  (setq ofd (* 25 12.0)) ; to feet if you are working in inches
  (while (setq ent (entsel "\nSelect object to offset or Enter to quit."))
    (OffsetDouble (car ent) ofd)
  )
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Error Traps
« Reply #6 on: October 26, 2004, 12:53:18 PM »
Real ugly but ...........
Code: [Select]

(defun OffsetDouble (ename dist / err_obj vobj enew)
  (setq vobj (vlax-ename->vla-object ename))
  (if (vlax-method-applicable-p vobj 'Offset)
   (progn
 (setq err_obj
(vl-catch-all-apply
  'vlax-invoke (list vobj 'Offset dist)
  )
)

(if (not (vl-catch-all-error-p err_obj))

 (setq err_obj
(vl-catch-all-apply
  'vlax-invoke (list vobj 'Offset (- dist))
  )
)
  )

(if (vl-catch-all-error-p err_obj)
 (prompt "\nCannot offset selected object type.")
)
)
  )
)
TheSwamp.org  (serving the CAD community since 2003)

daron

  • Guest
Error Traps
« Reply #7 on: October 26, 2004, 01:02:14 PM »
Thanks guys. I wasn't sure if that function would need much more. I know it needs what Keith said, I'm just looking for an alternate route. I thought maybe vl-return-with- functions might take the place or do a better job. Do you guys see any methods that might break it besides escape? I have some other procedures I'm working on and hoped to be able to figure those out for traps and thought I'd try and get some info here before plunging in.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #8 on: October 26, 2004, 01:15:09 PM »
Ok I see.
To use the vl-catch-all-apply you remove the parenthices from the function
and LIST the parameters even if there is only one parameter. So
this  (vlax-invoke vobj 'Offset dist)
become this (vl-catch-all-apply 'vlax-invoke (list vobj 'Offset dist)))
and if you want to test for the error you wrap it all in
this (if (vl-catch-all-error-p
so you could rewrite my function like this:
Code: [Select]
(defun OffsetDouble (ename dist / vobj enew)
  (setq vobj (vlax-ename->vla-object ename)
        enew '())
  (if (vlax-method-applicable-p vobj 'Offset)
    (progn
      (if (vl-catch-all-error-p
            (vl-catch-all-apply 'vlax-invoke
              (list vobj 'Offset dist)))
        (prompt "\nPositive distance failed.")
        (setq enew (list (entlast)))
      )
      (if (vl-catch-all-error-p
            (vl-catch-all-apply 'vlax-invoke
              (list vobj 'Offset (- dist))))
        (prompt "\nNegative distance failed.")
        (setq enew (cons (entlast) enew))
      )
    )
    (prompt "\nCannot offset selected object type.")
  )
); defun

Mark I noticed in some of your other routines you used this:
Code: [Select]
 (vl-catch-all-apply
    (function
      (lambda ()
        (and
          (equal (type msg) 'STR)
          (setq ent (entsel msg))
          (setq obj (vlax-ename->vla-object (car ent)))
          ); and
        (if
          (and obj (= (vla-get-ObjectName obj) objname))
          obj
          ; else
          (setq obj nil)
          )
        )
      )
    )

    Looks like the (function(lambda() are there to just wrap a chunk of code.
    So any error within that chunk will get trapped?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Error Traps
« Reply #9 on: October 26, 2004, 01:37:02 PM »
How about something along these lines;
Code: [Select]

(defun c:dbl-off (/ dist obj)
  (vl-load-com)

  ;; offsets the selected object in both directions
  ;; given one distance

  (defun get-utilobj ()
    (vla-get-utility
      (vla-get-activedocument
        (vlax-get-acad-object)
        )
      )
    )

  ; returns a VLA-OBJECT or nil
  ; user is prompted with standard "Select object:"
  (defun obj-select (/ obj pt)
    (if
      (not
        (vl-catch-all-error-p
          (vl-catch-all-apply
            'vlax-invoke-method
            (list (get-utilobj) 'GetEntity 'obj 'pt)
            )
          )
        ); not
      obj
      )
    )

  ; returns T if no errors in Offset command occur
  (defun my-offset (obj dist)
    (if
      (not
        (vl-catch-all-error-p
          (vl-catch-all-apply
            'vlax-invoke
            (list obj 'Offset dist)
            )
          )
        )
      T
      )
    )


  ;; ============== body of main function begins here ==============

  (initget 3); no null, no zero input
  (if (setq dist (getreal "\nOffset distance: "))
    (if (setq obj (obj-select))
      (if (vlax-method-applicable-p obj 'Offset)
        (if (my-offset obj dist)
          (if (not (my-offset obj (- dist)))
            (alert "Cannot offset blah blah blah")
            )
          )
        )
      )
    )
  (princ)
  )

TheSwamp.org  (serving the CAD community since 2003)

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Error Traps
« Reply #10 on: October 26, 2004, 01:41:28 PM »
Quote from: CAB
Mark I noticed in some of your other routines you used this:
Code: [Select]
 (vl-catch-all-apply
    (function
      (lambda ()
        (and
          (equal (type msg) 'STR)
          (setq ent (entsel msg))
          (setq obj (vlax-ename->vla-object (car ent)))
          ); and
        (if
          (and obj (= (vla-get-ObjectName obj) objname))
          obj
          ; else
          (setq obj nil)
          )
        )
      )
    )

    Looks like the (function(lambda() are there to just wrap a chunk of code.
    So any error within that chunk will get trapped?


That's the way I understand it. I believe Tony T was the one who showed me that.
TheSwamp.org  (serving the CAD community since 2003)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #11 on: October 26, 2004, 01:48:05 PM »
Thanks mark, but I wasn't trying to improve on the routine so much
as I was trying to explore the (vl-catch-all-error-p and (vl-catch-all-apply
functions and there implementation.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Error Traps
« Reply #12 on: October 26, 2004, 01:50:07 PM »
Just a note: Even the VLAX-METHOD-APPLICABLE-P becomes redundant when using VL-CATCH-ALL-APPLY

daron

  • Guest
Error Traps
« Reply #13 on: October 26, 2004, 01:53:45 PM »
That's what I'm after. Lisp has so many redundancies, I'm just not sure where to stop or which functions perform better than others.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Error Traps
« Reply #14 on: October 26, 2004, 03:00:42 PM »
Quote from: SMadsen
Just a note: Even the VLAX-METHOD-APPLICABLE-P becomes redundant when using VL-CATCH-ALL-APPLY

Good to know. So in my modified routine the only reason to use vlax-method-applicable-p
would be to differentiate between the type of error?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.