Author Topic: Share your ERROR subroutine to get best one  (Read 10465 times)

0 Members and 1 Guest are viewing this topic.

HasanCAD

  • Swamp Rat
  • Posts: 1421
Share your ERROR subroutine to get best one
« on: July 04, 2010, 04:42:48 AM »
Hi all

Lets share ERROR subroutine to get best one

mine is (I copied from a lisp)

Code: [Select]
  (defun *error* (msg)
    (and uFlag (vla-EndUndoMark doc))
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ))

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Share your ERROR subroutine to get best one
« Reply #1 on: July 04, 2010, 05:17:37 AM »
Hi,

IMO there's no 'best error subroutine'.
The error subroutine may be different for each main routine according to what you may have to reset:
- ending undo mark (no need to test uFlag with vla-EndUndoMark)
- restoring sysvar values
- closing an opened file
- erasing a temporary entity
- etc.
Speaking English as a French Frog

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Share your ERROR subroutine to get best one
« Reply #2 on: July 04, 2010, 09:42:41 AM »
I agree with gile. Here is MY basic error handler.
Code: [Select]
  (defun *error* (msg)
    (if (and msg (/= msg "") (not (wcmatch (strcase msg) "*QUIT*,*CANCEL*")))
       (princ (strcat "\nError: " msg))
    )
    (and usercmd (setvar "CMDECHO" usercmd))
    (and useros (setvar "osmode" useros))
    (princ)
  ) ; end error function
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.

efernal

  • Bull Frog
  • Posts: 206
Re: Share your ERROR subroutine to get best one
« Reply #3 on: July 04, 2010, 10:08:37 AM »
;; I use something like this:

Code: [Select]
(defun ef_my_error (s)
  (if ef_undo
    (progn (command "_.undo" "end") (command "_.u"))
  )
  (setq ef_undo nil)
  (if ef_lista_vars
    (foreach x ef_lista_vars (setvar (car x) (cadr x)))
  )
  (if (and opened_file (= (type opened_file) 'file))
    (close opened_file)
  )
  (if ef_old_error
    (setq *error* ef_old_error)
  )
  (princ "\n-> Erro : ")
  (princ s)
  (princ)
)

efernal


<edit: code tags added. >
« Last Edit: July 04, 2010, 11:41:42 AM by CAB »
e.fernal

Crank

  • Water Moccasin
  • Posts: 1503
Re: Share your ERROR subroutine to get best one
« Reply #4 on: July 04, 2010, 02:17:08 PM »
Another:
Code: [Select]
(defun c:DEMO ( / *error* *finish* Gb-varlist Gb-temperr)
(setq Gb-varList '("OSMODE" "DYNMODE" "BLIPMODE"); EXAMPLE OF THE VARIABLES YOU WANT TO RESTORE
      Gb-varList (mapcar (function (lambda (a) (list 'setvar a (getvar a)))) Gb-varList)
      Gb-temperr *error*)
(defun *finish* ()
(mapcar 'eval Gb-varList)(setq *error* Gb-temperr)(command "_.undo" "_end")
)
(defun *error* (msg)
(prompt (strcat "\nError: " msg))
(*finish*)
(command "_.u")
(princ)
)
(command "_.undo" "_be")

; Do your stuff

(*finish*)
(princ)
)
Vault Professional 2023     +     AEC Collection

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #6 on: July 04, 2010, 07:05:38 PM »
Code: [Select]
(defun *error* (msg)
  (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
    (princ (strcat "\nError: " msg))
  )
)
It basically does the same thing as Alan's, just with a little less legwork (notice the extra comma on the end).
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Hangman

  • Swamp Rat
  • Posts: 566
Re: Share your ERROR subroutine to get best one
« Reply #7 on: July 06, 2010, 12:05:17 PM »
Here is my error handling bungle.
Code: [Select]
  (defun *error* (msg /)
    (template:on-error msg)
    (princ)
  )

I borrowed this following piece from one of Kerry's posts, I like the way he put it together.
Code: [Select]
;; Error control  Thanks to Kerry - theSwamp
(pragma '((unprotect-assign template:on-error)))
;;
(defun template:on-error (msg / tmp)
;;----- Cancel any Active Commands -----------------------------
  (while
    (> (getvar "cmdactive") 0)
    (command)
  )
  (setvar "menuecho" 1)
  (command ".undo" "End" ".undo" "Back")
[color=green]; I've learned to only use the ".undo" command on lengthy routines where several things occur, and then with caution.[/color]
;;----- Display error message if applicable _-------------------
  (cond ((not msg))                          ; no error, do nothing
        ((member
           (strcase msg t)                   ; cancel
           '("console break" "function cancelled" "quit / exit abort")
         )
         (princ "\n\tFunction Cancelled\n\tFunction Cancelled")
        )
        ((princ (strcat "\nApplication Error: "
                        (itoa (getvar "errno"))
                        " :- "
                        msg "\n"
                )
         )
        )
  )
  ;;----- Reset System Variables ----------------
  (setvar "osmode" origOS)
  (setvar "autosnap" origASN)
  (setvar "menuecho" 0)
  (setvar "cmdecho" 1)
  (command ".redraw")
  (setq *error* nil)
  (princ)
)
;;
(pragma '((protect-assign template:on-error)))
;;

I've been slowly learning more and more about the functionality of error handling, and the more I learn, the more I learn there is so much more to learn than what I initially determined.
And I have recently discovered, as Gile pointed out:
Hi,

IMO there's no 'best error subroutine'.
The error subroutine may be different for each main routine according to what you may have to reset:
- ending undo mark (no need to test uFlag with vla-EndUndoMark)
- restoring sysvar values
- closing an opened file
- erasing a temporary entity
- etc.

And I am now wondering if it is worth having several small error handling cases in a large LiSP routine, each focusing on a particular issue, rather than one final error handling routine to cover any and all there is in the LiSP routine?.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Share your ERROR subroutine to get best one
« Reply #8 on: July 07, 2010, 05:59:59 AM »
I won't devote too much time or space to this 'cause there's a football match I want to watch shortly tonight.

Error trapping is a mechanism thats is quite often disregarded and frequently mis-understood.

The primary function of error trapping is twofold,
to attempt to advise the user when an error occurs
to attempt to restore the system to a state similar to it's previous condition

The level of trapping and handling will depend on the type of routines the programmer is developing.

I usually break the coding of error handlers into 2 phases.

Firstly I have a standard template and handler framework kept in my library,
then I add specific functionality to suit the type of routine being developed.

do we need to consider open file handles ;
have we any ActiveX objects that need to be released ;
will we write data to a log file ;
does the user deserve a slap on the wrist for the error ;
etc

Here's my core functions :
A function for saving the environment state prior to running a routine
A function for handling any error message itself.
A function for restoring the presaved environment.

Code: [Select]

;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;
(vl-load-com)
(or kglobal:acadapp (setq kglobal:acadapp (vlax-get-acad-object)))
(or kglobal:activedoc
    (setq kglobal:activedoc (vla-get-activedocument kglobal:acadapp))
)
;;;-----------------------------------------------------------------------
;;;
(defun kdub:on-error (msg / tmp)
  ;;----- Cancel any Active Commands -------------------------------------
  (while (< 0 (getvar "cmdactive")) (command))
  (setvar "menuecho" 1)
  (vla-endundomark kglobal:activedoc)
  ;;----- Display error message if applicable _---------------------------
  (cond
    ((not msg))                              ; no error, so do nothing
    ((member (strcase msg t)                 ; if cancel or quit
             '("console break" "function cancelled" "quit / exit abort")
     )
    )
    ((princ (strcat "\nApplication Error: " (itoa (getvar "errno")) " :- " msg))
     ;;----- Display backtrace ------------------------------------------
     (vl-bt)
    )
  )
  (setvar "errno" 0)
  ;;----- Release Bound Special Activex Objects --------------------------
  (foreach varname kglobal:objectsbound
    (if (= (type (setq tmp (vl-symbol-value varname))) 'vla-object)
      (if (not (vlax-object-released-p tmp))
        (vlax-release-object tmp)
      )
    )
    (set varname nil)
  )
  ;;----- Reset System Variables from global list ------------------------
  (foreach item kglobal:sysvarlist (setvar (car item) (cadr item)))
  ;;
  (setq kglobal:sysvarlist nil
        kglobal:objectsbound nil
  )
  (princ)
)




Code: [Select]
;;;-----------------------------------------------------------------------
;;; change sysvar value and save its previous value
  
(defun kdub:savesysvar (vars_list)
  ;; Save the values of these vars in case they are changed in the calling routine
   ;;    they will be saved with the vars listed in  vars_list
   ;; Note that some will be preset to ensure they meet the default values we require
   ;; If we want to override these simply add the items into the calling parameters
   ;;    in the calling routine
  (setq generalVars
            '(("CMDECHO"  0) ; save current and Turns off echoing
             ("expert"    ) ; save current value
             ("ORTHOMODE" ) ; save current value
             ("SNAPANG"   ) ; save current value
             ("UCSICON"   ) ; save current value
             ("SNAPMODE"  ) ; save current value
             ("OSMODE"    ) ; save current value
             ("PICKADD"  2) ; save current and  Turns on PICKADD. Shift-Pick to remove
             ("PICKAUTO" 1) ; save current and  Draws a selection window (for either a window or a crossing selection) automatically
             ("PICKBOX"  5) ; save current and  initial is 3. my default is 6
             ("INSUNITS" 0) ; save current and  Unspecified (No units)
             ("SORTENTS" 1) ; save current and  use selection Order to control
            )
   )  
  (foreach item  (append  vars_list generalVars)
    (setq kglobal:sysvarlist (cons (list (car item) (getvar (car item)))
                                   kglobal:sysvarlist
                             )
    )
    (if (cadr item)
      (setvar (car item) (eval (cadr item)))
    )
  )
)


Code: [Select]

;;;-----------------------------------------------------------------------
;;; ( kdub:restoresysvar )
(defun kdub:restoresysvar ()
  (foreach item kglobal:sysvarlist (setvar (car item) (cadr item)))
  (setq kglobal:sysvarlist nil)
  (princ)
)

These functions are loaded into each session in a VLX along with other library functions.

Then when writing routines it's simply a matter of calling those functions

Note that the *error* routine is declared LOCAL to the routine.

for example :

Code: [Select]

(vl-load-com)
(or kglobal:acadapp (setq kglobal:acadapp (vlax-get-acad-object)))
(or kglobal:activedoc
    (setq kglobal:activedoc (vla-get-activedocument kglobal:acadapp))
)

(defun c:DoItAgainSam ( / *error*
                      ;;
                      local vars go here
                      fileName fh escape result
                      )
  ;;-----------------------------------------------------------
  (defun *error* (msg)
    (kdub:on-error msg)
    ;;
    (vl-cmdf "_.UCS" "_Restore" prev:ucs)    
    (princ)
  )
  (vla-endundomark kglobal:activedoc)        ;close any open group
  (vla-startundomark kglobal:activedoc)      ;start new group
  ;;-----------------------------------------------------------
  ;; save the current value of these vars and set as noted
  ;; the values will be restored on exit or error.
  (kdub:savesysvar '(("CMDECHO"  0)
                     ("expert"   5)
                     ("PLINEGEN" 1)
                     ("BLIPMODE" 1)
                     ("CLAYER"    ) ; save current value               
                    )
  )
  (setq prev:ucs "TMP_ORIGINAL")
  (vl-cmdf "_.UCS" "_Save" prev:ucs)
  ;;-----------------------------------------------------------
  ;;-----------------------------------------------------------
  ;;

   ;; mojo goes here
  
   ;; comment out these statements to test
  (setq escape (getpoint "either pock a point or hit ESC"))

  (command "_.ucs" "Z" 75)
  ;;
  (command "_.Layer" "_M" "Test" "")

  (setq escape (getpoint "\nEither pick a point or hit ESC"))

  
  (setq fileName "Z:/NoFolderExists/NoFileExists.txt")
  (setq fh (open fileName "w"))

  (print fh "Stuff to add to file.")


  (setq result (/ 12.0 (getreal "\nEnter an number ... zero would be fun")))  
  ;; more mojo goes here

  ;; restore the vars if we get this far
  (kdub:restoresysvar)
  (princ)
)






 
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #9 on: July 07, 2010, 08:48:43 AM »
mine is (I copied from a lisp)

Hardly 'yours' since you copied it straight from one of my programs - the UndoMark is not needed in general anyway...

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #10 on: July 07, 2010, 08:50:24 AM »
mine is (I copied from a lisp)

Hardly 'yours' since you copied it straight from one of my programs - the UndoMark is not needed in general anyway...
I think he meant 'mine' as in that's the one he uses.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #11 on: July 07, 2010, 08:55:49 AM »
*shrug*  :|

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #12 on: July 07, 2010, 09:01:20 AM »
mine is (I copied from a lisp)

Hardly 'yours' since you copied it straight from one of my programs - the UndoMark is not needed in general anyway...

At least your stuff gets used; my stuff i cant give away?! I'm like that one guy in town that everybody kinda looks at funny like.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CHulse

  • Swamp Rat
  • Posts: 504
Re: Share your ERROR subroutine to get best one
« Reply #13 on: July 07, 2010, 09:05:47 AM »
*shrug*  :|

I must admit, I use one of Lee's also - but I take no credit...

Code: [Select]
;; --{  Error Handler Function  }--
;; by Lee Mac ~ 2010

  (defun *error* (msg)     ...

You should be flattered :)

Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #14 on: July 07, 2010, 09:13:52 AM »
You should be flattered :)

Don't get me wrong, I am flattered when I see my code being used by others - but I just get peeved when code is blatently copy/pasted with no credit as to the source is all.


alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #15 on: July 07, 2010, 09:27:19 AM »
You should be flattered :)

Don't get me wrong, I am flattered when I see my code being used by others - but I just get peeved when code is blatently copy/pasted with no credit as to the source is all.


It's a generic error handler. Do you give credit to whom you got the usage of wcmatch in the error handler from?
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #16 on: July 07, 2010, 09:34:32 AM »
You should be flattered :)

Don't get me wrong, I am flattered when I see my code being used by others - but I just get peeved when code is blatently copy/pasted with no credit as to the source is all.



Honestly, ask yourself: why?  
Let it go man. I'll give you a story. This one time (at band camp) I had a very sneaking suspicion that one guy i knew took my code and assembled a ``for sale program''. I was so weird about the whole situation that I started to work on a VLX and FAS decompiler so i could check. Do you have any idea how long it takes to map out a file structure like that with a hex editor (It takes a long time).  After about a week i started to make some progress and then i realized what i was doing and how much time I was wasting.  ...who cares (chin up)?

Besides, how complicated is this stuff anyways? Not very! Chances are that i could have wrote that very same thing 6 years ago and you then are the copy cat (so there :P ).
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #17 on: July 07, 2010, 09:37:45 AM »
True, perhaps I'm getting worked up over nothing - I know that its only a small amount of code, and simple to write, but what got me was that there was no attempt at understanding the code that was used, clearly demonstrated by the Undomark being left in there. But you are right - I've said my piece, I'll leave it now.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #18 on: July 07, 2010, 09:40:53 AM »
Don't lie, you just want to see your name in lights as much as possible.  :lmao:
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #19 on: July 07, 2010, 09:47:22 AM »
<snip> what got me was that there was no attempt at understanding the code that was used... <snip>

*Phhhttt!* Yeah tell me about it. I post genius all day and i dont even get as much as "hey thats a cool idea".
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #20 on: July 07, 2010, 09:49:03 AM »
<snip> what got me was that there was no attempt at understanding the code that was used... <snip>

*Phhhttt!* Yeah tell me about it. I post genius all day and i dont even get as much as "hey thats a cool idea".
I think everyone feels that way, at least at some point.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

pkohut

  • Guest
Re: Share your ERROR subroutine to get best one
« Reply #21 on: July 07, 2010, 10:15:27 AM »
<snip> what got me was that there was no attempt at understanding the code that was used... <snip>

*Phhhttt!* Yeah tell me about it. I post genius all day and i dont even get as much as "hey thats a cool idea".
:-D :-D :-D
U-2, eh!

But as far as what Lee is talking about, let it go. Not everyone *wants* to understand the code they use,
some just want to put together a "patchwork quilt of pieces" to get something that works for them. On the
other hand continue to educate those that want to learn and participate. BTW, how long you been programming
anyways? Cause you've got some "elite" skills.  :kewl:


Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #22 on: July 07, 2010, 10:30:25 AM »
Thanks Paul - that is high praise indeed considering the source  :-)  I started about a year and a half or so ago, but only in the relatively simple world of LISP - I'd love to do what you guys can do in C++/Arx.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #23 on: July 07, 2010, 11:02:11 AM »
When I grow up, I hope to have 'elite' skills like some here.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

pkohut

  • Guest
Re: Share your ERROR subroutine to get best one
« Reply #24 on: July 07, 2010, 11:12:47 AM »
When I grow up, I hope to have 'elite' skills like some here.

Things you lispers' can do is mazing!

LE3

  • Guest
Re: Share your ERROR subroutine to get best one
« Reply #25 on: July 07, 2010, 11:18:20 AM »
When I grow up, I hope to have 'elite' skills like some here.
Me too.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #26 on: July 07, 2010, 11:19:20 AM »
When I grow up, I hope to have 'elite' skills like some here.
Me too.
Psh, you'll never grow up.  :laugh:
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #27 on: July 07, 2010, 11:48:30 AM »
"[you]" = whomever


[you] want "attempt to understand" the code?

Why did [you] choose to use OR the way you did?
Code: [Select]
(or (wcmatch (strcase errmsg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\nError: " errmsg " **")))

Why did you terminate it after the first PRINC statement (technically speaking: there would be no difference if you terminated after the second princ)?
Code: [Select]
(or (wcmatch (strcase errmsg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\nError: " errmsg " **"))
    (princ))

Why did [you] choose OR over something simpler to understand like COND?
Code: [Select]
(cond
      ((wcmatch (strcase errmsg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " errmsg " **")))
    )

The way [you] use OR in the previous is confusing. In fact it would be less confusing and more straightforward if [you] choose to use IF or COND.

Why did'nt [you] at least stop all commands?
Code: [Select]
(repeat 2 (command))
Why did [you] choose the name "*error*" and not something like "MYERRHNDLR"
...
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #28 on: July 07, 2010, 12:01:18 PM »
My answer:

Why did [you] choose to use OR the way you did?

To save from an 'if, not' - OR looks and feels tidier "Either the msg is matched with ... , OR we print it".

Why did you terminate it after the first PRINC statement (technically speaking: there would be no difference if you terminated after the second princ)?

Yes there would, if the OR was terminated after the second 'princ', the second 'princ' would not be evaluated as the previous expression returns True. And secondly, the OR would be the last function call so we would have a return of T.

Why did [you] choose OR over something simpler to understand like COND?
Code: [Select]
(cond
      ((wcmatch (strcase errmsg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " errmsg " **")))
    )

Again, just aesthetics I suppose...

Why did'nt [you] at least stop all commands?
Code: [Select]
(repeat 2 (command))

I tend not to use command statements in my code.

Why did [you] choose the name "*error*" and not something like "MYERRHNDLR"

I localise the *error* symbol in my code hence performing the same result as restoring the default handler.


How did I do?

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #29 on: July 07, 2010, 12:35:56 PM »
> I tend not to use command statements in my code.

why? There is nothing wrong with COMMAND if you are prepared for it. Besides, two commands like that means <ESCAPE> <ESCAPE>

> ...the second 'princ' would not be evaluated as the previous expression returns True...

See what i mean about confusing? `aesthetics' be damed. [you] or someone needs to maintain this. Make it easier on yourself; ditch the fancy obscure tricks and focus on the elegance.

Why even check the string if your not going to print it if it passes the check BTW? I'm actually kinda confused.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #30 on: July 07, 2010, 12:37:09 PM »
(setq olderr *error* *error* ErrorTrap)
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #31 on: July 07, 2010, 01:25:48 PM »
> I tend not to use command statements in my code.

why? There is nothing wrong with COMMAND if you are prepared for it. Besides, two commands like that means <ESCAPE> <ESCAPE>

I find most command calls unreliable and of course there is the performance aspect to consider - so I only use them if I have no other alternative or unless the alternative is 100's of lines of code...

> ...the second 'princ' would not be evaluated as the previous expression returns True...

See what i mean about confusing? `aesthetics' be damed. [you] or someone needs to maintain this. Make it easier on yourself; ditch the fancy obscure tricks and focus on the elegance.

I don't think two lines within an OR is confusing - its practically an  (if (not <xxx>) (then <xxx>) ...), it was you that suggested including the second princ in the statement - at which point it may become a little obscure...

Why even check the string if your not going to print it if it passes the check BTW? I'm actually kinda confused.

Again, the OR acts like an (if (not <xxx>) (then <xxx>) ...) - I am checking the string so that I don't print the 'Function Cancelled' etc messages.

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #32 on: July 07, 2010, 02:02:15 PM »
TOOL - Ænima is a very good album to debug code to.



TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Share your ERROR subroutine to get best one
« Reply #33 on: July 08, 2010, 03:48:59 AM »

Lee,
John has an ongoing fixation about OR and COND .... you may ignore him if you like.    :lmao:
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Share your ERROR subroutine to get best one
« Reply #34 on: July 08, 2010, 06:13:28 AM »

just a thought :

Don't we all stand on  the shoulders of giants ( a little ).
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

HasanCAD

  • Swamp Rat
  • Posts: 1421
Re: Share your ERROR subroutine to get best one
« Reply #35 on: July 08, 2010, 06:25:31 AM »

just a thought :

Don't we all stand on  the shoulders of giants ( a little ).

YES we are.

CHulse

  • Swamp Rat
  • Posts: 504
Re: Share your ERROR subroutine to get best one
« Reply #36 on: July 08, 2010, 07:08:51 AM »

just a thought :

Don't we all stand on  the shoulders of giants ( a little ).

... or a lot! I know I'd be lost without the help of all of you here and at Cadtutor. I can atribute almost everything I know about cad to these forums ("self" taught)...
So Thanks.
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Share your ERROR subroutine to get best one
« Reply #37 on: July 08, 2010, 08:16:26 AM »

just a thought :

Don't we all stand on  the shoulders of giants ( a little ).

I suppose you hit the nail on the head - I too learn most of what I know from others examples  :-)

TimSpangler

  • Water Moccasin
  • Posts: 2010
  • CAD Naked!!
Re: Share your ERROR subroutine to get best one
« Reply #38 on: July 08, 2010, 08:18:00 AM »
TOOL - Ænima is a very good album to debug code to.





Thats a good album to do anything to.  It was the best live show I had ever seen.
ACA 2015 - Windows 7 Pro
All Comments and Content by TimSpangler, Copyright © 2016

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Share your ERROR subroutine to get best one
« Reply #39 on: July 08, 2010, 08:18:45 AM »
It was the best live show I had ever seen.
Agree. Both times.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: Share your ERROR subroutine to get best one
« Reply #40 on: July 08, 2010, 09:36:31 AM »
Lee,
John has an ongoing fixation about OR and COND .... you may ignore him if you like.    :lmao:

Its not a `fixation'. *Under breath: I'll fix you.*

That is only because OR returns a Boolean value not...no, wait (let me just say it)...it is *not* the same as "(if (not (<blah>...".

IMHO if you want to use OR that way then you should just switch to Scheme otherwise do what the rest of us do; use IF and or COND.  However, i am not totally against the use of OR in some situations. I think OR can be a very elegant method but *I* know how to use it and i feel that most times the user just thinks its a fancy trick. Hence, my comment about debugging code. Ive hunted down these "boolean errors" and seen what happens when you dont "know your returns" can do to the flow of an app and i say good luck.


:P
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MeasureUp

  • Bull Frog
  • Posts: 462
Re: Share your ERROR subroutine to get best one
« Reply #41 on: July 09, 2010, 02:19:14 AM »
When these in different positions in the codes
Code: [Select]
[color=red]   (setq theERR *error*)
   (setq *error* ErrorHandling)[/color]
would the following codes make any difference?
Thanks for your helps.

Code: [Select]
(defun Test (/ *error* theERR)
   (defun ErrorHandling (msg)
    ...
   ); end of ErrorHandling
   ...
   MainFunctions Here
   ...
   [color=red](setq theERR *error*)
   (setq *error* ErrorHandling)[/color]
); end of Test

Code: [Select]
(defun Test (/ *error* theERR)
   (defun ErrorHandling (msg)
    ...
   ); end of ErrorHandling
   [color=red](setq theERR *error*)
   (setq *error* ErrorHandling)[/color]
   ...
   MainFunctions Here
   ...
); end of Test

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Share your ERROR subroutine to get best one
« Reply #42 on: July 09, 2010, 02:34:16 AM »
It's actually simpler than that.

You don't need the variable theERR  or the local-function  ErrorHandling

The *error* function is LOCAL to the routune ... so you don't need to be concerned with any global function named the same  (the acad default one) that may exist.


I'd do it like this :
Code: [Select]
(defun Test (/ *error* )
   (defun *error* (msg)
    ...
   ); end of ErrorHandling
   ...
   MainFunctions Here
   ...

  (princ)
); end of Test


for fun, have a look at the code I posted .. you'll see a statement that MAY cause a divide by zero error.
See if you can write a self contained routine that will trap that (or  in fact any) error.

Post the code when you're done. :)


[added]
BUT, if you wanted to use the methodology you posted, the second sample is correct.
The *error* function alias needs to be declared before it can be used ... so declare it after the handler definition
  
« Last Edit: July 09, 2010, 02:39:59 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MeasureUp

  • Bull Frog
  • Posts: 462
Re: Share your ERROR subroutine to get best one
« Reply #43 on: July 09, 2010, 03:05:02 AM »
Thanks.
What if the ErrorHandling function is outside of the Test code?

Sample 3
Code: [Select]
(defun ErrorHandling (msg)
    ...
); end of ErrorHandling

(defun Test (/ *error* theERR)
      ...
   MainFunctions Here
   ...
   [color=red](setq theERR *error*)
   (setq *error* ErrorHandling)[/color]
(princ)
); end of Sample 3

Sample 4
Code: [Select]
(defun ErrorHandling (msg)
    ...
); end of ErrorHandling

(defun Test (/ *error* theERR)
   [color=red](setq theERR *error*)
   (setq *error* ErrorHandling)[/color]
      ...
   MainFunctions Here
   ...
(princ)
); end of Sample 4

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Share your ERROR subroutine to get best one
« Reply #44 on: July 09, 2010, 03:14:32 AM »
Thanks.
What if the ErrorHandling function is outside of the Test code?

<.. >

In that case, simply do it like the following sample.

Just to clarify :
The AutoLisp engine looks for a function called *error* to handle breaks in evaluation.
If there is a Global function named *error* it will be used if no LOCAL *error* function is declared

Code: [Select]


(defun Test4a (/ *error* )
   (defun *error* (msg)
     ;; call the external handler
     (ErrorHandling msg)
     ;; do local handling
    ...
   )
   ;; ----- end of ErrorHandling -----

      ...
   MainFunctions Here
   ...
(princ)
); end of Sample 4a


kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MeasureUp

  • Bull Frog
  • Posts: 462
Re: Share your ERROR subroutine to get best one
« Reply #45 on: July 12, 2010, 07:30:50 PM »
Thanks to all.

Sam

  • Bull Frog
  • Posts: 201
Re: Share your ERROR subroutine to get best one
« Reply #46 on: July 16, 2010, 07:57:30 AM »

Quote
;;;m_redraw----objectives highlighted

;;;m_delss-----in the Program Run-time generated temporary objects

;;;m_hbdraw-----in the program Setup This value to determine whether mistakes redraw Graph

;;;m_setFirst------run in the interimSelectSet


(defun hb_error   (a /)

  (if

    (not

      (member a

         '("Function is cancelled"
      "Function cancelled"
      "quit / exit abort"
          )

      )

    )

     (princ a)

  )

  (if m_redraw

    (cond

      ((member (type m_redraw) (list 'ename))

       (redraw m_reDraw 4)

       (setq m_reDraw nil)

      )

      ((= (type m_redraw) 'list)

       (MAPCAR '(LAMBDA (itm) (redraw itm 4))

          m_redraw

       )

       (setq m_reDraw nil)

      )

    )

  )

  (if m_hbdraw

    (redraw)

  )

  (if m_delss

    (progn

      (vl-cmdf "_.erase" m_delss "")

      (setq m_delss nil)

    )

  )

  (if m_setFirst

    (sssetfirst nil nil)

  )

  (HB_SETVAR m_lst) ;_m_lst saved for the initialization System Variable value


  (setq *error* olderr)

  (vla-EndUndoMark VLAXDOC)

)

;|«Visual LISP© Format Options»
(200 2 40 2 nil "end of " 60 9 0 0 nil T T nil T)
;*** DO NOT add text below the comment! ***|;
Every time we waste electricity, we put our planet's future in the dark. Let's turn around our attiude and start saving power and our planet, before it's too late
http://www.theswamp.org/donate.html

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Share your ERROR subroutine to get best one
« Reply #47 on: July 17, 2010, 07:17:48 AM »
My $0.02

Code: [Select]
(setq olderr *error*
      *error* (lambda (msg)
                (while (> (getvar "CMDACTIVE") 0)
                       (command))
                (and (/= msg "quit / exit abort")
                     (princ (strcat "\nError: *** " msg " *** ")))
                (and (= (logand (getvar "UNDOCTL") 8) 8)
                     (command "_.UNDO" "_END" "_.U"))
                (nw_rmd)))  ;;; My Mode Reset

-David
R12 Dos - A2K