error handling problem

Discussion in 'AutoCAD' started by Phil, May 7, 2004.

  1. Phil

    Phil Guest

    I keep getting a blank command line after my error messages. See
    following example.

    (defun c:test( / )
    (defun myerr (s)
    (if (/= s "Function cancelled")
    (if (= s "quit / exit abort")
    (princ)
    (princ s)
    )
    )
    (if orgerr (setq *error* orgerr))
    (princ)
    )
    (setq orgerr *error* *error* myerr)
    (princ "\nan error message")
    (exit)
    )

    this gives me the following in my text area so I can not see the error
    msg without having 3lines or hitting f2.:
    command:test
    an error message
    command:
    command:_

    How can I get it to do like:

    command:test
    an error message
    command:_
     
    Phil, May 7, 2004
    #1
  2. Phil

    Mark Propst Guest

    just some thoughts off the top
    depending on what version you're on you dont need to save the old error
    object(i think since r14?)
    one possibility would be: (there are lots of better examples around if you
    want to google)
    (defun test(/ *error*);localize error object and global one is unharmed
    (defun *error*(msg)
    (cond
    ((and
    msg
    (/= msg "Function cancelled")
    (= msg "quit / exit abort")
    );and
    (princ msg)
    )
    (;any other cond choices you want
    (= something true)
    (princ somethingelse)

    );etc
    );cond
    ;regardless of kind of error
    (reset stuff)
    (princ);if desired
    );end err

    ;then test it out
    (badfunction)
    (princ)
    )

    <<<
    if you need to save the old one it would be like this
    (setq orgerr *error* )
    ;not
    beginning --- if it were necessary
    beginning, not the end

    ;;;though it's unnecessary to define a function, then setq *error* to it,
    just defun *error* and localize as above
    ;;;;exit is probably not required here since in an error condition you're
    already on the way out.
    ;;; and i've always heard it's the worst way to stop a program - even if
    this weren't the last line of an error trap.
     
    Mark Propst, May 8, 2004
    #2
  3. Phil

    Phil Guest

    Thanks, I will try that, I always localize my err routine so thanks for
    that tip
     
    Phil, May 8, 2004
    #3
  4. Phil

    Tom Smith Guest

    Thanks, I will try that, I always localize my err routine so thanks for
    that tip

    To avoid repetitive coding, I use a generic error handler that's defined on
    startup, so all my functions can call it:

    (defun init-err (varlist / oce)
    (setq *error*
    (append
    '((msg / oce))
    (mapcar
    '(lambda (var) (list 'setvar var (getvar var)))
    varlist)
    '((setq oce (getvar "cmdecho")))
    '((setvar "cmdecho" 0))
    '((command "undo" "end"))
    '((setvar "cmdecho" oce))
    '((princ msg))
    '((princ))))
    (setq oce (getvar "cmdecho"))
    (setvar "cmdecho" 0)
    (command "undo" "begin")
    (setvar "cmdecho" oce)
    (princ))

    It takes a list of variables and creates an *error* function on the fly at
    runtime. Usage:

    (defun c:myfunction (/ *error* <localvar> <etc>)
    (init-err '(<var1> <var2> <etc>))
    ;do whatever
    (*error* "\nDone."))

    Notice that the error handler is called on normal termination as well as on
    an error condition like hitting ESC. This guarantees that the function will
    end in the same way whether or not an error occurs.
     
    Tom Smith, May 10, 2004
    #4
  5. Phil

    Phil Guest

    I've been studying ways to make it generic, I like your idea. I've been
    using the *error* handler for general cleanup as well.
     
    Phil, May 12, 2004
    #5
  6. Phil

    Tom Smith Guest

    I've been studying ways to make it generic, I like your idea. I've been
    I've seen people do elaborate cleanup routines separately from error
    handling, and there never seems to be a need, since you want your program to
    terminate the same way in either case. I don't know how the error function
    can be truly generic unless it's composed at runtime.

    This wasn't an original idea, I gleaned the concept from other discussions.
    I'm pretty sure some ideas came from afralisp, probably some from acadx, and
    so forth. The express tools do something similar, I think. They add another
    twist, which might be nice (but I haven't needed) -- an undo flag which if
    set causes the error handler to do an undo back.

    This would be useful if your routine was "doing" something in the Acad
    environment at the time it was cancelled -- making or deleting things, or
    whatever -- so that the environment would be completely restored to where it
    was before the routine ran. But then you'd have to distinguish between
    normal cleanup vs conditions that required an undo. (Probably you'd only
    want an undo on cancel.)

    As it is, this error routine works for the fairly modest programs I write.
    Usually I try to arrange them to gather all the user input first, do
    whatever pre-processing or number-crunching is necessary, keeping all that
    info in local variables, and then do all the graphical/environmental changes
    in one swoop. Normally this is so fast that it's unlikely the user could
    cancel it in progress, and if he did, he can still undo it with a single U
    because of the undo marks in the error handler.

    Not perfect, but simple, and good enough for my purposes.
     
    Tom Smith, May 12, 2004
    #6
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.