Author Topic: one error catch for several lisps in a macro  (Read 3566 times)

0 Members and 1 Guest are viewing this topic.

Hangman

  • Swamp Rat
  • Posts: 566
one error catch for several lisps in a macro
« on: December 17, 2007, 03:58:08 PM »
Hey guys, curiosity question here.
I have a macros.lsp file with several routines in it.  Very simple, small routines.  Because of their simplicity, most do not have an error catch in them.
How would you guys put a single error catch for ALL of the routines in the macros.lsp ??

Another question, would you consider this to be an efficient way of using/catagorizing your small simple routines ??
Hangman  8)

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

JohnK

  • Administrator
  • Seagull
  • Posts: 10657
Re: one error catch for several lisps in a macro
« Reply #1 on: December 17, 2007, 06:01:43 PM »
Ive seen/used several methods for this kinda thing; What your thinking about is usually called a ``global'' error trap (or something like that). I dont like to use them anymore cause one error trap isnt good in every situation. For example, if you look for the error trap i posted in the ``show your stuff'' forum you would notice that its big time overkill for small apps that only issue a command.

Soemthing like:

Code: [Select]
(defun c:Toggle-TileMode ()
  (setvar "tilemode"  (boole 6 (getvar "tilemode") 1)) )

Putting an error trap on something like this is idiotic; There's not really a need.

However implimenting something like this:

Code: [Select]
(defun c:myline ( / toggleOsnap)
  ;;
  ;; Define support procedures.
     (defun toggleOsnap (value)
       ;; toggleOsnaps
       ;;
       ;; This function accepts a integer of 1 or 0 (on or off) to set the
       ;; end users osnap value to enabled or disabled.
       ;;
       ;; Argument: 1 = Enable the users osnaps
       ;;           0 = Disable the users osnaps
       ;;
       ;; Usage: (toggleOsnap 1) or (toggleOsnap 0)
       ;;
       (setvar "OSMODE" (boole (- 7 value) (getvar "OSMODE") 16384))
       (princ)
       )
  ;; End support procedures.

  (toggleOsnap 0)
  ;; Turn the osnaps off.

  ;; Lets draw aline...
  (command "_line")
  ;; Now that the line command has begun,
  ;; be quite and wait till the user finishes.
  (while (eq (getvar 'cmdactive) 1)
         (command PAUSE))
  ;; now that we are done with the line command,
  ;; let's turn the osnaps back on.
  (toggleOsnap 1)
)

in a department or comany of people, lends itself to problems. So a small error trap can be used to help.

Like so:

Code: [Select]
(defun c:myline ( / toggleOsnap)
   ;;
   ;; Define support procedures.
   (defun toggleOsnap (value)
     ;; toggleOsnaps
     ;;
     ;; This function accepts a integer of 1 or 0 (on or off) to set the
     ;; end users osnap value to enabled or disabled.
     ;;
     ;; Argument: 1 = Enable the users osnaps
     ;;           0 = Disable the users osnaps
     ;;
     ;; Usage: (toggleOsnap 1) or (toggleOsnap 0)
     ;;
     (setvar "OSMODE" (boole (- 7 value) (getvar "OSMODE") 16384))
     (princ)
     )
 
   (defun Oh-boy!? (s)
     (setq *error* olderr
           olderr  nil)

      (toggleOsnap 1)
     (princ)
     )
   ;; End support procedures.

   (setq olderr *error* *error* Oh-boy!?)
   ;; use my err trap instead.

   (toggleOsnap 0)
   ;; Turn the osnaps off.

   ;; Lets draw aline...
   (command "_line")
   ;; Now that the line command has begun,
   ;; be quite and wait till the user finishes.
   (while (eq (getvar 'cmdactive) 1)
          (command PAUSE))
   ;; now that we are done with the line command,
   ;; were done, lets get outta here.
   (Oh-boy!? "")
 )

This small error trap makes it better, but again this is a custom application and they by no means need to be even this complicated. But on the flip side, this cant be used in a large application with any sort of comfort either. Most procedures need a small, if any, error trappings and that is why/how I created the one I posted--Its more a starting point, or even good enough in some-.

NOW, if we want to talk about something like a full blown ``custom lisp loaders'' or ``on-the-fly procedure creating'' something like:
Code: [Select]
( (lambda ( func )
    (list (cons 'lambda (cons nil (list func))))
    )
 '(+ 1 2))
we could be here all day but I think what is above is more along the lines what your talking about.



Yes, I do the same.



I hope I didnt confuse you.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: one error catch for several lisps in a macro
« Reply #2 on: December 17, 2007, 06:11:56 PM »
Interesting! Very interesting!
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Hangman

  • Swamp Rat
  • Posts: 566
Re: one error catch for several lisps in a macro
« Reply #3 on: December 17, 2007, 07:44:30 PM »
Ive seen/used several methods for this kinda thing; What your thinking about is usually called a ``global'' error trap (or something like that). I dont like to use them anymore cause one error trap isnt good in every situation.

I see, and you have a good point in that one size doesn't fit all.  I too have several simple commands where no other input is needed like your toggle-tilemode example.  I have no error trap on these, but I do have it on several others, and it is the same for every routine I have in the macros.lsp file.  The only difference is the sys-variables and such being reset.  Some have more, some less than this example:
Code: [Select]
(defun $error (msg /)
    (if (or (= msg "Function cancelled") (/= msg "quit / exit abort"))
        (princ (strcat "Error: " msg))
    )
    (command ".undo" "e" "undo" "")
    (setvar "cmdecho" 1)
    (setvar "osmode" osprev)
    (setvar "clayer" layprev)
    (setvar "autosnap" asnprev)
    (command ".redraw")
    (setq *error* old_err
         osprev nil
         layprev nil
         asnprev nil
    )
    (princ)
  );end error
 

I can see some issues in using this example as a "global" error trap, and on the other hand, I can see a good use for it as a global error trap.
So, in essence, if you keep your macros.lsp file with simple routines, all basically using the same sys-variables and setq's, you should be fine with a global error trap?.
Hangman  8)

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

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: one error catch for several lisps in a macro
« Reply #4 on: December 17, 2007, 09:38:20 PM »
Generally speaking, my observation, perspective and opinion ...

More frequently what is required is the necessity to either code more defensively or catch an operation that could fail, so a solution can deal with it gracefully, such as reseting sysvars, active layers et al., rather than rely on the *error* function.

Solutions that bomb and invoke *error* are in need of design review to remedy the "unanticipated event(s)".

Core functions, which are the building blocks of solutions, should generally not employ error handling code (throw low, catch high).

Other "errors" shouldn't be trapped at all. For example, if I pass a real to a function that expects a string it should bomb. Right now. Period. It shouldn't be masked by an error handler. It's a design flaw.

What's my point?

There are always exceptions, but generally speaking the only error handler I employ is (defun *error* (x) (vl-bt)) which usually tells me exactly where my programming failed so I can go about remedying the shortcomings in the solution's current design.

But what if the user leans on the [esc] key?

I say throw random ones and zeros at them; stick your tongue out.

~ ~ ~

Of all the opinions I've posted here this was my most recent.

:)
« Last Edit: December 17, 2007, 10:29:54 PM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: one error catch for several lisps in a macro
« Reply #5 on: December 17, 2007, 10:41:38 PM »
There are always exceptions, but generally speaking the only error handler I employ is (defun *error* (x) (vl-bt)) which usually tells me exactly where my programming failed so I can go about remedying the shortcomings in the solution's current design.
Interesting! Very interesting!
Tell me more!
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: one error catch for several lisps in a macro
« Reply #6 on: December 17, 2007, 11:57:00 PM »

I say throw random ones and zeros at them; stick your tongue out.

~ ~ ~

Of all the opinions I've posted here this was my most recent.

:)

 :-D

Quote
Solutions that bomb and invoke *error* are in need of design review to remedy the "unanticipated event(s)".

To me, that is the core of it !
assertionTest,  assertionTest, assertionTest ...

.. I do however catch the ESC ... and tell the user I closed (past tense) because of it.


general observation :
'error trapping' and 'environment restoration' are 2 different things, and should be treated accordingly.

my design philosophy for today :-
'Everything will work just as you expect it to, unless your expectations are incorrect.'
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.

JohnK

  • Administrator
  • Seagull
  • Posts: 10657
Re: one error catch for several lisps in a macro
« Reply #7 on: December 18, 2007, 11:22:48 AM »
I agree with MP and Kerry, code defensively and test, try, break, redo, etc.. The best beta tester for your new program is the worst drafter in your office.

There is a very strong underlying topic brewing here...
There comes a point when you do have to pass control to the end user and  you must count the fact that (s)he will press escape or pick a tool bar.

In most of my code, I exit gracefully if the user pressed esc. I do not send an alert box telling them their feet stink and ask them to give it another go around; I just assume they want off the ride so, i let em off. I also do not send, change, whatever env or sys vars until ive tested and setup and ive built up enough info im comfortable in how i can handle that esc. key being pressed (I think i understand at which point it might occur).

P.S.
Kerry, I like the wording of your design philosophy. Very nicely put.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Hangman

  • Swamp Rat
  • Posts: 566
Re: one error catch for several lisps in a macro
« Reply #8 on: December 19, 2007, 03:41:32 PM »
Ditto to MP's philosophy, although it's usually my expectations that are incorrect.   ;-)
One of the reasons I started this topic, is because of my macros.lsp file having a glitch.  Although I cannot find it, it is because of the esc key in the middle of a command.  Hence the question of a global error trap rather than several individual ones.
So Se7en, how do you gracefully exit when the esc key is hit ?  How do all of you exit when the esc key is hit ?
Usually, the esc key is hit because of the lack of thinking ahead far enough to realize the proper steps in accomplishing a task.  I try to eliminate the 'thinking ahead' part when writing code, but it gets rather difficult if not impossible at times.
Kerry, you mentioned:
...
general observation :
'error trapping' and 'environment restoration' are 2 different things, and should be treated accordingly.
I have recently discovered this aspect as a user hit the escape key in the middle of a command and it took him back several commands, eliminating half of what was just designed and drawn.  It restored the environment, but didn't trap the error (or in this case, the esc key).
But I do not know where it is coming from.  Do you have any suggestions I can try to find this little discrepency ?  I know it's like looking for a needle in a haystack, and I'm hoping you guys will have some comments and thoughts which will help me reduce the amount of 'hay' I have to sift through.

Thank you all for your input, this is very, very informative.  You can't get this kind of information from a book, it comes from experience.  Which is why were here right ?, you guys are great !!
Hangman  8)

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

JohnK

  • Administrator
  • Seagull
  • Posts: 10657
Re: one error catch for several lisps in a macro
« Reply #9 on: December 19, 2007, 04:08:29 PM »
<snip>
Kerry, you mentioned:
...
general observation :
'error trapping' and 'environment restoration' are 2 different things, and should be treated accordingly.
I have recently discovered this aspect as a user hit the escape key in the middle of a command and it took him back several commands, eliminating half of what was just designed and drawn.  It restored the environment, but didn't trap the error (or in this case, the esc key).
<snip>

I'll try and build an example later, but this is basically what we are talking about; In the case of a esc, I restore the env and exit, while others may choose to keep the user in the program.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10657
Re: one error catch for several lisps in a macro
« Reply #10 on: December 19, 2007, 05:22:26 PM »
Read this: [ http://www.theswamp.org/index.php?topic=13730.0 ] and get back to me when you understand how to use it.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

DEVITG

  • Bull Frog
  • Posts: 481
Re: one error catch for several lisps in a macro
« Reply #11 on: December 20, 2007, 01:36:00 PM »
(defun *error* (x) (vl-bt))

Hi, could you explain what function is?
Quote

(vl-bt)
 
 
Location @ Córdoba Argentina Using ACAD 2019  at Window 10

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: one error catch for several lisps in a macro
« Reply #12 on: December 20, 2007, 02:18:12 PM »
(vl-bt) Performs a back trace on the most previous error.

e.g.

(/ 1 0) [enter]

Backtrace:
[0.44] (VL-BT)
[1.40] (*ERROR* "divide by zero")
[2.35] (_call-err-hook #<SUBR @0649bfc8 *ERROR*> "divide by zero")
[3.29] (sys-error "divide by zero")
:ERROR-BREAK.24 nil
[4.21] (/ 1 0)
[5.15] (#<SUBR @0675c604 -rts_top->)
[6.12] (#<SUBR @05d22334 veval-str-body> "(/ 1 0)" T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)

It was an undocumented function that was given first light by Tony Tanzillo, with whom we owe much for his abundant, varied, insightful and valuable contributions over the years.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: one error catch for several lisps in a macro
« Reply #13 on: December 20, 2007, 02:50:54 PM »
Here's a little something I wrote many moons ago.

http://www.theswamp.org/index.php?topic=3385.msg41436#msg41436

I hope it makes sense!
TheSwamp.org  (serving the CAD community since 2003)