See the top rated post in this thread. Click here

Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: Error Handling

  1. #11
    The Silent Type RobertB's Avatar
    Join Date
    2000-01
    Location
    Seattle WA USA
    Posts
    5,859
    Login to Give a bone
    0

    Exclamation Re: Error Handling

    Quote Originally Posted by ticad02 View Post
    Either I'm missing something or I just can't figure it out. I've tried all the mentioned ideas and haven't come up with anything that works. I can't even trouble shoot my attempts as I don't know if I'm even writing the right code in the right places. I'm pretty much just shooting in the dark (lisp at its finest LOL).

    I've attached my three attempts maybe someone can make heads or tails out of what my problem is. Note1.lsp jams up ACAD and I have to go to the task manager to close it. By the way I'm using ACAD 2010 if that changes anything.

    I don't want it written for me, I won't learn anything that way, but if I had a little more guidance about where I was going wrong I may be able to get an the right path.

    Thanks again for everyones patienece and advice.
    What immediately jumps out at me is the nested functions. It looks like you are taking the posted sample code and attempting to just "wrap" it around your real code. Rather, you should modify your function so that it is similar to the posted samples.

    The two functions myerror and MyExit are really intended to do the same thing: clean up after a clean exit or an error. However, most of the system variable restores are being done in myerror whereas MyExit is being used too.

    I suggest moving all the system variable restores to MyExit and then get rid of the function nesting and unneeded statements as shown here in green. (Any added item will be in red.)

    Code:
    ; This routine draws a leader w/arrow and text.
    ;
    (defun myerror (s)
    (if
     (or
     (= msg "Function cancelled")
     (= msg "quit / exit abort")
     )
     (princ)
     (princ (strcat "\nError: " msg))
    )
    (if (/= s "Function cancelled")
      (princ (strcat "\nError: " s)))
    (command "layer" "s" userlay "")
    (command "linetype" "s" userlt "")
    (command "color" "bylayer")
    (setvar "cmdecho" userecho)
    (setvar "orthomode" userortho)
    (setvar "clayer" userla)
    (setvar "pickbox" userpick)
    (setq *error* olderror)
    (princ)
    )
    
    (defun secure (/ fp)
    (setvar "cmdecho" 0)
    (if (= (getvar "USERR3") 0.0)
      (progn (print)(print)(print)
    	 (alert "System variables not set, please re-run\nthe SETUP routine to continue...")
    	 (exit)))
    )
    
    (defun MyExit (msg)
     (cond 
      ((not msg)) ; no error, normal exit
      ((member msg '("Function cancelled" "quit / exit abort"))) ; <esc> or (quit)
      ((princ (strcat "\nError: " msg)))) ; error, display it
      (setvar "clayer" userlay)
      (setvar "celtype" userlt)
      (setvar "cecolor" "bylayer")
      (setvar "cmdecho" userecho)
      (setvar "orthomode" userortho)
      (setvar "clayer" userla)
      (setvar "pickbox" userpick)
      (setvar "polaraddang" "")
      (setvar "osmode" useros)
     (princ))
    
    (defun C:MainCode (/ *Error*) ; localize error handler
     (setq *Error* MyExit) ; redefine local error handler
    
    (defun C:srs (/ *error* dsc da la ls ep ang ang1 p1 p2 th tx txthght olo oln oll ls1 userla useras userpm)
    (secure)(print)(print)
    (setq olderror *error* *error* myerror)
    (setq *error* MyExit)
    (setq userpick (getvar "pickbox"))
    (setq dsc (getvar "USERR3"))
    (setq userecho (getvar "cmdecho"))
    (setq userla (getvar "clayer"))
    (setq userortho (getvar "orthomode"))
    (setq useros (getvar "osmode"))
    (setq userlay (getvar "clayer"))
    (setq userlt (getvar "celtype"))
    (setvar "orthomode" 0)
    (setvar "cmdecho" 0)
    (setq th (* 9.0 (/ dsc 96.0)))
    (if (= 1 (getvar "userr2")) (setq th (* 12.0 (/ dsc 96.0))))
    (setvar "osmode" 512)
    
    (setq useras (getvar "autosnap"))
    (setq userpm (getvar "polarmode"))
    (command "polarmode" "4")
    (command "polaraddang" "30;60;120;150;210;240;300;330")
    (command "autosnap" "13")
    
    (setq olo (entsel "\nSelect referenced object..."))
    ;(setq ls (car(cdr olo)))
    (setq oln (car olo))
    (setq oll (entget oln))
    (setq la (cdr (assoc 8 oll)))
    (setq la (substr la 1 3))
    (setq la (strcat la "TX"))
    
    (setq laY (cdr (assoc 8 oll)))
    (setq laY (substr laY 1 7))
    (setq laY (strcat laY "TEXT"))
    
    
    (setq ls (getpoint "\nLeader start <nearest>..."))
    (setvar "osmode" 0)
    
    (command "iNSERT" "loop3" ls (/ dsc 96.0) (/ dsc 96.0) da)
    (setvar "DIMASZ" 0.046875)
    (setvar "DIMCLRD" 3)
    (setvar "DIMCLRE" 3)
    (setvar "DIMCLRT" 4)
    (setvar "DIMscale" (getvar "USERR3"))
    (setvar "DIMLDRBLK" "LOOP3")
    
    (setq ep (getpoint ls "\nNext point..."))
    (setq ang (angle ep ls))
    (setq ang1 pi)
    (if (and (> ang (/ pi 2.0)) (< ang (* 1.5 pi))) (setq ang1 0.0))
    (setq p1 (polar ep ang1 (* 6.0 (/ dsc 96.0))))
    (setq p2 (polar p1 ang1 (* 2.0 (/ dsc 96.0))))
    (if (= nil (tblsearch "layer" la))
      (command "layer" "m" la "c" "c" la "lt" "continuous" la ""))
    (command "layer" "s" la "")
    
    (if (= nil (tblsearch "layer" laY))
    (if (= 2 (getvar "userr2"))(command "layer" "m" laY "c" "c" laY "lt" "continuous" laY "")))
    (if (= 2 (getvar "userr2"))(command "layer" "s" laY ""))
    
    (command "color" "g")
    (command "linetype" "s" "continuous" "")
    (setq da (* (+ ang pi) (/ 180.0 pi)))
    ;(command "insert" "arrow" ls (/ dsc 96.0) (/ dsc 96.0) da)
    (command "LEADER" ls ep p1 "F" "A" "" "" "N")
    (command "color" "c")
    ;(setq tx (getstring T "\nEnter text string : "))
    (setq txthght (getvar "textsize"))
    (if (NOT (= th txthght))
       (progn
       (command "style" "hand" "" "0" "1" "0" "n" "n" "n")
       (if (= 1 (getvar "userr2")) (command "style" "lwa8g" "" "0" "0.8" "0" "n" "n" "n"))
    
    (if (= 2 (getvar "userr2")) (command "style" "lwa8g" "" "0" "0.8" "0" "n" "n" "n"))
    )
    )
    (command "style" "" "" "0" "" "0" "n" "n" "n")
    (princ "\nInput Text (2 enters to quit):")
    (if (> (car ep) (car p1))
    (command "Dtext" "j" "mr" p2 th 0)
    (command "Dtext" "j" "ml" p2 th 0)
    )
    
    (setvar "polarmode" userpm)
    (setvar "autosnap" useras)
    (command "polaraddang" ".")
    (command "layer" "s" userlay "")
    (command "color" "bylayer")
    (command "linetype" "s" userlt "")
    (setvar "cmdecho" userecho)
    (setvar "orthomode" userortho)
    (setvar "pickbox" userpick)
    (setvar "clayer" userla)
    (setvar "osmode" useros)
    (setq *error* olderror)
    (MyExit nil)) ; normal, clean exit
    (print)(print)
    )
    R. Robert Bell
    Design Technology Manager
    Stantec
    Opinions expressed are mine alone and do not reflect the views of Stantec.

  2. #12
    Member
    Join Date
    2007-03
    Posts
    32
    Login to Give a bone
    0

    Default Re: Error Handling

    Its working now, thank you. I had multiples of the same things happening and it seems they were fighting each other over it. I also didn't have "error" defined in my list

    (defun C:srs (/ *error* dsc da la ls ep ang ang1 p1 p2 th tx txthght olo oln oll ls1 userla useras userpm useros)

    I added useros as well, though I don't think I have to. I'm under the impression that any defined variable should be listed there, is that correct?

    I'm getting a better understanding of how a proper error code is wrote, and I'll start putting it in all my routines. I also think the error code that was in there was old and may not have worked properly.

    Thank you all for the help.

  3. #13
    The Silent Type RobertB's Avatar
    Join Date
    2000-01
    Location
    Seattle WA USA
    Posts
    5,859
    Login to Give a bone
    0

    Default Re: Error Handling

    Quote Originally Posted by ticad02 View Post
    Its working now, thank you. I had multiples of the same things happening and it seems they were fighting each other over it. I also didn't have "error" defined in my list

    (defun C:srs (/ *error* dsc da la ls ep ang ang1 p1 p2 th tx txthght olo oln oll ls1 userla useras userpm useros)

    I added useros as well, though I don't think I have to. I'm under the impression that any defined variable should be listed there, is that correct?

    I'm getting a better understanding of how a proper error code is wrote, and I'll start putting it in all my routines. I also think the error code that was in there was old and may not have worked properly.

    Thank you all for the help.
    Yeah, any variables you create in your routine should be declared as local, which is any variable in that first nested paren pair after the forward slash character. You can use the VLIDE to check the code for any variables that are global and add those to the list. Note that that mechanism is a bit flawed and will report some variables as global even when they are local depending on how they are used and reports ActiveX enums as global variables (which I suppose they technically are).
    R. Robert Bell
    Design Technology Manager
    Stantec
    Opinions expressed are mine alone and do not reflect the views of Stantec.

  4. #14
    AUGI Addict
    Join Date
    2006-04
    Location
    (getpoint "Anywhere on the Enter Key =>")
    Posts
    1,160
    Login to Give a bone
    0

    Default Re: Error Handling

    I know this is an old thread but have a question for your guys:
    Is it good if I have a separate file for this function & to load it automatically when AutoCAD starts?
    If it is not necessary, what is a nice way to organize the routines for those common functions?
    And I don't need to add this portion to each routine.
    Thanks for your help.

  5. #15
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: Error Handling

    There's pros & cons to both:
    • Separate file pros:
      • Only one file which can be used from any routine
      • Always works consistently
    • Separate file cons:
      • Difficult to modify for special cases
      • Much more involved routine, since all probable scenarios need to be taken into account
    • Per Lisp Error handler pros
      • Error trap routine is efficient & small (at least if you design it this way)
      • Can easily be modified to suit special cases without breaking anything else
    • Per Lisp Error handler cons
      • Can't easily be reused in another routine ... may need modifications
      • Consistency could become a thing of the past
    There's probably a few more. But you can see from above that it's more of a subjective decision on your part. In most cases it would be easier to have a single error handler which you always call (and use) in the same way. This does not mean it's the "best" way though, since there may be some alternative settings to change which you haven't thought of when making the error handler. But it's generally easier to edit one file than hundreds if something's wrong .

    I lean towards a separate file to load for all routines, but that's just me.

  6. #16
    AUGI Addict
    Join Date
    2006-04
    Location
    (getpoint "Anywhere on the Enter Key =>")
    Posts
    1,160
    Login to Give a bone
    0

    Default Re: Error Handling

    Quote Originally Posted by irneb View Post
    There's pros & cons to both:
    • Separate file pros:
      • Only one file which can be used from any routine
      • Always works consistently
    • Separate file cons:
      • Difficult to modify for special cases
      • Much more involved routine, since all probable scenarios need to be taken into account

    • Per Lisp Error handler pros
      • Error trap routine is efficient & small (at least if you design it this way)
      • Can easily be modified to suit special cases without breaking anything else
    • Per Lisp Error handler cons
      • Can't easily be reused in another routine ... may need modifications
      • Consistency could become a thing of the past
    There's probably a few more. But you can see from above that it's more of a subjective decision on your part. In most cases it would be easier to have a single error handler which you always call (and use) in the same way. This does not mean it's the "best" way though, since there may be some alternative settings to change which you haven't thought of when making the error handler. But it's generally easier to edit one file than hundreds if something's wrong .

    I lean towards a separate file to load for all routines, but that's just me.
    This is a nice explanation / tip.
    Thank you very much.

  7. #17
    AUGI Addict
    Join Date
    2015-12
    Posts
    2,095
    Login to Give a bone
    0

    Default Re: Error Handling

    I use a "global" error handler function to handle the whoopsies (nil values, strings instead of reals, etc.) as well as system variable restoration. In cases where more specific error handling is needed (which is pretty rare) I create a new function, swap it out for the global handler, and have the specific error handler code restore the global error handler if called. The "global" error handler function and a number of supporting functions reside in their own file for organization purposes, plus it also has execute-on-load behavior so the handler is established just be loading the file.

Page 2 of 2 FirstFirst 12

Similar Threads

  1. Error Handling
    By whattaz13 in forum AutoLISP
    Replies: 2
    Last Post: 2008-07-16, 01:03 PM
  2. Error Handling
    By jwf in forum AutoCAD Customization
    Replies: 2
    Last Post: 2004-12-03, 07:42 PM
  3. Error Handling:
    By spencer.67965 in forum AutoLISP
    Replies: 4
    Last Post: 2004-09-15, 09:18 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •