- UID
- 5
- 积分
- 2526
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-3
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×

- <body>
- <table cellSpacing="0" cellPadding="2" width="100%" bgColor="#e0e0e0" border="0">
- <tbody>
- <tr>
- <td><font face="arial,sans-serif">
- <table cellSpacing="0" cellPadding="0" align="right" border="0">
- <tbody>
- <tr>
- <td></td>
- </tr>
- </tbody>
- </table>
- </font>寄件者:<font face="arial,sans-serif"><a href="http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&oe=UTF-8&q=author:tony.tanzillo%40worldnet.att.net+">Tony
- Tanzillo</a> (<a href="mailto:tony.tanzillo@worldnet.att.net">tony.tanzillo@worldnet.att.net</a>)<br>
- </font>主旨:<font face="arial,sans-serif">Re: Globally Cath
- Exeptions<br>
- </font>新闻群组:<font face="arial,sans-serif"><a href="http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&oe=UTF-8&group=autodesk.autocad.customization">autodesk.autocad.customization</a><br>
- <table cellSpacing="0" cellPadding="0" align="right" border="0">
- <tbody>
- <tr>
- <td><font face="arial,sans-serif">View: <a href="http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&oe=UTF-8&threadm=37F00043.775B4094%40worldnet.att.net&rnum=2&prev=/groups%3Fhl%3Dzh-CN%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D37F00043.775B4094%2540worldnet.att.net%26rnum%3D2">Complete
- Thread (6 articles)</a> | <a href="http://groups.google.com/groups?selm=37F00043.775B4094%40worldnet.att.net&oe=UTF-8&output=gplain">Original
- Format</a></font></td>
- </tr>
- </tbody>
- </table>
- </font>日期:<font face="arial,sans-serif">1999/09/27<br>
- </font></td>
- </tr>
- </tbody>
- </table>
- <pre>I'm not sure I understand what you mean by 'not clean'.
- The very nature of exception handling mandates that
- the application specifically prepare for and deal
- with exceptions locally, so that it can resume its
- execution or terminate gracefully (e.g., clean up).
- You have to remember that exceptions are used both
- for errors, and for signaling conditions like user-
- input was not provided, an option keyword was entered,
- or a collection key was not found. These types of
- exceptions _must_ be handled locally and explicitly.
- If you were to wrap your entire program inside one
- exception handler in your main command function, it
- would catch the exception, but that's essentially
- like using *error*, because the execution of your
- code will still be suspended at the point where the
- exception occurred, and control will be transferred
- to the next expression that follows the protected
- expression (the code passed to vl-catch-all-apply):
- <font color="#0000FF" face="Courier New">(defun C:YOURCOMMAND ( / rslt)
- (setq rslt
- (vl-catch-all-apply
- '(lambda ()
- (run-your-application)
- )
- )
- )
- (if (vl-catch-all-error-p rslt)
- (alert
- (strcat
- "This expression is evaluated immediately "
- "after the one in which the exception occurred"
- )
- )
- rslt
- )
- )</font>
- The above is really no different than this:
- <font color="#0000FF" face="Courier New">(defun C:YOURCOMMAND ( / *error*)
- (defun *error* (msg)
- (alert
- (strcat
- "This expression is evaluated immediately "
- "after the one in which the exception occurred"
- )
- )
- )
- (run-your-application)
- )</font>
- So, what good is the former?
- There are some tricks that a very skilled programmer
- can do, to wrap the body of every function in their
- program in its own exception handler, but that doesn't
- really solve the problem, other than perhaps serving
- as a debugging tool. That's because the way you handle
- an exception depends on both the nature of the error,
- and how/where/when/why it occurs.
- Here's a helper function that can make localized
- exception handling a bit less frustrating:
- <font color="#0000FF" face="Courier New">;; (catch-error <Protected> <OnError>)
- ;;
- ;; (catch-error
- ;; '(lambda () <code to protect>...)
- ;; '(lambda (error) <error handling code>...)
- ;; )
- ;;
- ;; A wrapper for vl-catch-all-xxxxxxx
- ;;
- ;; This function provides a high-level exception-handling
- ;; construct that allows the programmer to factor out some
- ;; of the testing and flow control required when using the
- ;; vl-catch-all-xxxxx functions directly (which is messy).
- ;;
- ;; (catch-error) takes two arguments, both of which are
- ;; quoted function names or lambda lists:
- ;;
- ;; <Protected> is a function that takes no arguments
- ;; (usually a lambda list). It is evaluated, and if an
- ;; error occurs during its evaluation, then <OnError> is
- ;; called and passed the error string.
- ;;
- ;; <OnError> is a function that is called only if an error
- ;; occurs during the evaluation of <Protected>. In that case,
- ;; the message returned by (vl-catch-all-error-message) is
- ;; passed to <OnError> as its only argument.
- ;;
- ;; If no error occurs during evaluation of <Protected>, then
- ;; (catch-error) returns the result of <Protected>. If an error
- ;; occurs during evaluation of <Protected>, then (catch-error)
- ;; returns the result of <OnError> if supplied. If an error
- ;; occurs and <OnError> is not supplied (e.g., nil), then
- ;; (catch-error) returns the Visual LISP error object that
- ;; triggered the error.
- ;;
- ;; By default, errors are always handled. The only way to
- ;; re-raise the error is to call (exit) from within <OnError>,
- ;; and is generally what should be done in cases where the
- ;; error is unknown or the code in the <OnError> error handler
- ;; is not equipped to deal with a particular type of error.
- ;;
- ;; Note that calls to (catch-error) can be nested, such that
- ;; if a nested call does not handle an error (by calling exit
- ;; or vl-exit-with-error), then one or more outer calls can
- ;; also examine and/or handle the error, with the caveat that
- ;; the error message is not the same as the original one, if
- ;; you use (exit). If you use (vl-exit-with-error), then the
- ;; error message is correct, but in that case the outer most
- ;; call to (catch-all) must handle the error because it cannot
- ;; call (exit) to invoke the *error* function.
- ;;
- ;; In essence, you can think of each call to
- ;; catch error to be a temporary and locally-bound
- ;; redefinition of the *error* function (where the
- ;; <OnError> argument represents the body of *error*),
- ;; with the added benefit of being able to resume
- ;; execution if desired.
- ;;
- ;;
- ;; Example:
- ;;
- ;; The following code obtains a point or the
- ;; option keyword "foo", and traps the error
- ;; that occurs if the user responds with the
- ;; option keyword.
- ;;
- ;; If the error is not a result of the user
- ;; entering the keyword, then something else
- ;; has gone wrong. In that case, the error
- ;; handler displays the error message, and
- ;; aborts by calling (exit).
- ;;
- ;; If no error occurs, then the error handler
- ;; is not called, and the user-supplied point
- ;; is assigned to Result
- ;;
- ;; (defun C:CATCH-ERROR-TEST ()
- ;;
- ;; (setq eKeyWordInput
- ;; "Automation Error. User input is a keyword"
- ;; )
- ;;
- ;; (setq Util
- ;; (vla-get-utility
- ;; (vla-get-activeDocument
- ;; (vlax-get-acad-object)
- ;; )
- ;; )
- ;; )
- ;;
- ;;
- ;; (vla-IntializeUserInput Util 0 "Foo")
- ;;
- ;; (setq result
- ;; (catch-error
- ;; '(lambda ()
- ;; (vla-Getpoint
- ;; Util nil "Enter point/Foo: "
- ;; )
- ;; )
- ;; '(lambda (error)
- ;; (if (eq error eKeyWordInput)
- ;; (vla-GetInput Util)
- ;; (progn
- ;; (alert (strcat "Error: " errmsg))
- ;; (exit)
- ;; )
- ;; )
- ;; )
- ;; )
- ;; )
- ;;
- ;; (if (eq (type Result) 'Str)
- ;; (princ "\nUser entered 'FOO'")
- ;; (princ "\nUser entered a point")
- ;; )
- ;;
- ;; (princ)
- ;;
- ;; )
- ;;
- (defun catch-error (catch:Protected catch:OnError / catch:err)
- (setq catch:err
- (vl-catch-all-apply catch:Protected)
- )
- (if (and (vl-catch-all-error-p catch:err)
- catch:OnError
- )
- (Apply catch:OnError
- (list (vl-catch-all-error-message catch:err))
- )
- catch:err
- )
- )
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- </font></pre>
- </body>
|
|