+ Reply to Thread
Results 1 to 7 of 7
  1. #1
    Super Member lamensterms's Avatar
    Computer Details
    lamensterms's Computer Details
    Operating System:
    Windows 7 - 64bit
    Discipline
    Manufacture
    lamensterms's Discipline Details
    Occupation
    Steel Detailer
    Discipline
    Manufacture
    Details
    3D Modelling - Mechanical & Structural 2D Detailing - Shop Drawings
    Using
    AutoCAD 2014
    Join Date
    May 2011
    Location
    Berwick, VIC, Australia
    Posts
    566

    Unhappy Error trapper undoing too much...

    Registered forum members do not see this ad.

    Hey,

    We're having an ongoing issue with some of our LISP routines, specifically the error trapper/handler. The problem is that sometimes upon 'error', too many actions will be undone.

    My assumption is... (and I'm happy to have this disputed)... one LISP routine's error handler is using "UNDO" "BACK", but the routine itself does not place an "UNDO" "MARK".

    So upon 'error' the trapper is issuing "UNDO" "BACK" and undoing to the previous MARK set, not one that should be in the routine being crashed. Does this sound right?

    Having said all that, does anyone have any suggestions on how to find which routine would be stuffing it up? Below is the code for a routine that undid everything (well.. back to the previous mark) upon 'error'. But this routine does have a "UNDO" "MARK" set... so it shoot my theory down.

    Either way, I'm struggling to solve this one and would greatly appreciate any help in uneathing the guilty routine.

    Thanks a lot.

    Code:
    (defun uzerr (s)
    (command "undo" "b")
     (prompt "\n*Program Terminated***UZ.lsp ERROR MESSAGE*")
    (setq *error* exi)
    (princ)
    )
    
    (Defun c:UZ (/ pnt1 pnt2 os orth)
    (setq uzcmde (getvar "cmdecho"))
    (setvar "cmdecho" 0)
    (command "undo" "m")
    (setq exi *error*)
    (setq *error* uzerr)
    (setq OS (getvar "osmode"))
    (setq ORTH (getvar "orthomode"))
    (setvar "osmode" 512)
    (command "UCSICON" "ON")
    (setq PNT1 (getpoint "\nPick first point, nearest to - or press enter to turn off nearest osnap..."))
    (setvar "orthomode" 0)
    (if (= PNT1 nil)
     (progn
      (setvar "osmode" OS)
      (prompt "\nPick two points to align X axis...")
      (command "ucs" "z" pause pause)
     ) 
     (progn
      (initget 1)
      (setq PNT2 (getpoint PNT1 "\nPick second point - Nearest to ..."))
      (setvar "osmode" 0)
      (command "ucs" "z" PNT1 PNT2)
      (setvar "osmode" OS)
     )
    )
    (setvar "orthomode" ORTH)
    (setq *error* exi)
    (setvar "cmdecho" uzcmde)
    (princ)
    )

  2. #2
    Super Member lamensterms's Avatar
    Computer Details
    lamensterms's Computer Details
    Operating System:
    Windows 7 - 64bit
    Discipline
    Manufacture
    lamensterms's Discipline Details
    Occupation
    Steel Detailer
    Discipline
    Manufacture
    Details
    3D Modelling - Mechanical & Structural 2D Detailing - Shop Drawings
    Using
    AutoCAD 2014
    Join Date
    May 2011
    Location
    Berwick, VIC, Australia
    Posts
    566

    Default

    After a little more investigation (and education - thanks to Lee Mac's article here... http://www.lee-mac.com/errorhandling.html) I have now realised that none of my LISP routines have the temporary *error* function/symbol defined as a local variable. So some (and I'm guessing there will be a few) of my routines are defining *error* as the temporary function, specific to that routine, but are then not restoring *error* to its default function.

    This explains the issues I've had with UNDO > BACK (being that I have had a temporary *error* function set, while it should be set to default).

  3. #3
    Quantum Mechanic Lee Mac's Avatar
    Computer Details
    Lee Mac's Computer Details
    Operating System:
    Windows 7 Ultimate (32-bit)
    Discipline
    Multi-disciplinary
    Lee Mac's Discipline Details
    Discipline
    Multi-disciplinary
    Details
    Custom Programming / Software Customisation
    Using
    AutoCAD 2013
    Join Date
    Aug 2008
    Location
    London, England
    Posts
    18,969

    Default

    Quote Originally Posted by lamensterms View Post
    After a little more investigation (and education - thanks to Lee Mac's article here... http://www.lee-mac.com/errorhandling.html) I have now realised that none of my LISP routines have the temporary *error* function/symbol defined as a local variable. So some (and I'm guessing there will be a few) of my routines are defining *error* as the temporary function, specific to that routine, but are then not restoring *error* to its default function.
    Although you are not following the route of declaring the *error* symbol local to the function, your current code still follows the method I describe under the heading 'An Alternative to Function Localisation', so the previous *error* function will still be restored.
    Lee Mac ProgrammingTwitterExchange App StoreDropbox (500MB free)

    With Mathematics there is the possibility of perfect rigour, so why settle for less?

  4. #4
    Super Member lamensterms's Avatar
    Computer Details
    lamensterms's Computer Details
    Operating System:
    Windows 7 - 64bit
    Discipline
    Manufacture
    lamensterms's Discipline Details
    Occupation
    Steel Detailer
    Discipline
    Manufacture
    Details
    3D Modelling - Mechanical & Structural 2D Detailing - Shop Drawings
    Using
    AutoCAD 2014
    Join Date
    May 2011
    Location
    Berwick, VIC, Australia
    Posts
    566

    Default

    Thanks Lee. I think the example code I originally posted may not be an offending routine.

    I've got some routines that I believe are not closing out completely. For example, I've got a routine that initiates Block Edit, and I think the Block Editor is launched before the routine calls for the *error* symbol to be restored to default. I understand (or, I hope I understand), that localising of the *error* symbol will remedy that particular case.

    Happy to be steered in the right direction though.

    Thanks a lot for the reply.

  5. #5
    Super Member lamensterms's Avatar
    Computer Details
    lamensterms's Computer Details
    Operating System:
    Windows 7 - 64bit
    Discipline
    Manufacture
    lamensterms's Discipline Details
    Occupation
    Steel Detailer
    Discipline
    Manufacture
    Details
    3D Modelling - Mechanical & Structural 2D Detailing - Shop Drawings
    Using
    AutoCAD 2014
    Join Date
    May 2011
    Location
    Berwick, VIC, Australia
    Posts
    566

    Default

    Hey again guys.

    I just lost a long, detailed post so forgive me if this one is a little brief.

    We are still having this issue.

    I'm at a bit of a loss, as time goes on, and I correct more erroneous routines, we should be seeing this problem less and less, but it still pops up occasionally. Now I'm starting to doubt if I actually understand the problem at all.

    Does anyone have any advice on another approach to correct this problem? Or how to identify the offending routines to fix?


    I have read here: http://forums.autodesk.com/t5/visual...rk/td-p/863544 ... that it's not wise to use UNDO MARK in LISP routines. Is there any truth to that? I followed AFRALISP's error handler example for UNDO MARK & BACK, should I change to UNDO BEGIN & END?
    Any other advice would be greatly appreciated.

  6. #6
    Super Member
    Discipline
    Multi-disciplinary
    Using
    AutoCAD 2015
    Join Date
    Nov 2013
    Posts
    743

    Default

    I always use the vla-EndUndoMark/vla-StartUndoMark methods, check this fragment with description from Lee:
    Code:
    (setq doc (vla-get-activedocument (vlax-get-acad-object)))
    (if (= 8 (logand 8 (getvar 'undoctl))) ;; If an undo group is already open
      (vla-endundomark doc) ;; close it
    ) ;; end if
    (vla-startundomark doc) ;; Open a new undo group
    (vla-endundomark doc) ;; Close the open undo group
    Where between Start and Endundomark must be located the expressions, that perform changes on the drawing (like changing object's property value).
    Also I think that when using the UNDO command, a command-s call must be used when its within the *error* function, otherwise something like this is enough:
    Code:
      (defun *error* ( msg )
        (and acDoc (= 8 (logand (getvar 'undoctl) 8)) (vla-EndUndoMark acDoc))
        (princ msg)
        (princ)
      )

  7. #7
    Super Member lamensterms's Avatar
    Computer Details
    lamensterms's Computer Details
    Operating System:
    Windows 7 - 64bit
    Discipline
    Manufacture
    lamensterms's Discipline Details
    Occupation
    Steel Detailer
    Discipline
    Manufacture
    Details
    3D Modelling - Mechanical & Structural 2D Detailing - Shop Drawings
    Using
    AutoCAD 2014
    Join Date
    May 2011
    Location
    Berwick, VIC, Australia
    Posts
    566

    Default

    Registered forum members do not see this ad.

    I think I've been able to reproduce this error now, and have found some confusing clues/results:

    There are 3 LISP routines used in these tests, please see below:

    CODE#1
    Code:
    (defun C:BI2NOSCALING (/)
    (SETVAR "CMDECHO" 0)
       (prompt "\nPICK INSERTION POINT. ")
       (SETQ SCALE "1") 
    (SETVAR "CMDECHO" 1)
       (COMMAND "INSERT" BLOCK pause "" scale pause)
    (SETVAR "CMDECHO" 0)
    (command "explode" "L")
       (terpri)
    )


    CODE#2
    Code:
    (defun c:mi ( / *error* MIss MIpt1 MIpt2 OROS ORORT)
     (SETQ OROS (GETVAR "OSMODE"))
     (SETQ ORORT (GETVAR "ORTHOMODE"))
    (command "undo" "m")
    ;(command "undo" "m")
     (SETVAR "OSMODE" 0)
     (SETVAR "ORTHOMODE" 1)
     (SETVAR "cmdecho" 0)
     ;(COMMAND "undo" "END")
     (setq exi *error*)
     (setq *error* MIerr)
     (setq MIss (ssget))
     (setq MIpt1 (getpoint))
     (command "ucs" "O" MIpt1)
     (setq MIpt2 '( 0 0 0))
     (SETVAR "cmdecho" 1)
     (command "mirror" MIss "" MIPT2 pause pause)
     (command "ucs" "P")
     (SETVAR "OSMODE" OROS)
     (SETVAR "ORTHOMODE" ORORT)
     (SETVAR "cmdecho" 0)
     (setq *error* exi)
     (princ)
    )


    CODE#3
    Code:
    (defun c:mi ( / *error* MIss MIpt1 MIpt2 OROS ORORT)
     (SETQ OROS (GETVAR "OSMODE"))
     (SETQ ORORT (GETVAR "ORTHOMODE"))
    (command "undo" "m")
    (command "undo" "m")
     (SETVAR "OSMODE" 0)
     (SETVAR "ORTHOMODE" 1)
     (SETVAR "cmdecho" 0)
     ;(COMMAND "undo" "END")
     (setq exi *error*)
     (setq *error* MIerr)
     (setq MIss (ssget))
     (setq MIpt1 (getpoint))
     (command "ucs" "O" MIpt1)
     (setq MIpt2 '( 0 0 0))
     (SETVAR "cmdecho" 1)
     (command "mirror" MIss "" MIPT2 pause pause)
     (command "ucs" "P")
     (SETVAR "OSMODE" OROS)
     (SETVAR "ORTHOMODE" ORORT)
     (SETVAR "cmdecho" 0)
     (setq *error* exi)
     (princ)
    )


    Error Handler
    Code:
    (defun MIerr (s)
     (command "undo" "b")
     (prompt "\n*Program Terminated***Mirror.lsp ERROR MESSAGE*")
     (setq *error* exi)
     (princ)
    )

    Test 1 - No Problem Produced
    In a new drawing (no undo history), if I run CODE#1 completely, then CODE#2 but ESC out of routine at prompt for 2nd point... No problem.

    Test 2 - No Problem Produced
    In a new drawing (no undo history), if I run CODE#1 completely, then CODE#3 but ESC out of routine at prompt for 2nd point... No problem.

    Test 3 - Problem Produced
    In a new drawing (no undo history), if I run CODE#1 completely, then hit RETURN & then ESC, then run CODE#2 but ESC out of routine at prompt for 2nd point... Problem.

    Test 4 - No Problem Produced

    In a new drawing (no undo history), if I run CODE#1 completely, then hit RETURN & then ESC, then run CODE#3 but ESC out of routine at prompt for 2nd point... No Problem.

    I'm finding it hard to make sense out of this, but my observations are: if I ESC out of CODE#1 before ESCing out of CODE#2, the problem occurs. But it I ESC out of CODE#1 before ESCing out of CODE#3, no problem occurs. The only difference between CODE#2 & CODE#3 is that CODE#3 has the (command "undo" "m") line duplicated. It seems that there is a possibility that a single (command "undo" "m") line will be ignored (or something). But if I run CODE#2 after successfully completing the previous command... no problem.

Similar Threads

  1. Undoing Phantom Commands
    By CyberAngel in forum AutoCAD Bugs, Error Messages & Quirks
    Replies: 11
    Last Post: 23rd Jan 2015, 04:11 pm
  2. Error Trapper Failing...
    By lamensterms in forum AutoLISP, Visual LISP & DCL
    Replies: 0
    Last Post: 18th Sep 2013, 03:29 am
  3. Replies: 22
    Last Post: 21st Jan 2013, 04:04 pm
  4. Undoing Lisps
    By bagulhodoido in forum AutoLISP, Visual LISP & DCL
    Replies: 7
    Last Post: 3rd Feb 2009, 12:23 pm
  5. Undoing mods to xref inplace
    By nchesh in forum AutoCAD Drawing Management & Output
    Replies: 1
    Last Post: 14th Jan 2005, 08:40 pm

Bookmarks

Posting Permissions

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