Answers:
我想到了两个选择,但都不是完美的。首先,您可以将大多数早期初始化代码(即,在进入自定义项之前)包装在中(ignore-errors ...)
。如果有错误,但不会有很大的回响- ignore-errors
将简单地返回nil
。
一个更复杂的选择是将unwind-protect
和组合在一起的潜在错误代码with-demoted-errors
(debug-on-error
设置为nil)。后者会在遇到第一个错误时优雅地出错,并将错误消息报告给*Messages*
缓冲区以供您检查。同时,unwind-protect
将评估正文的其余部分(可能是您的自定义)。因此,例如:
(unwind-protect
(let ((debug-on-error nil))
(with-demoted-errors
(message "The world is about to end")
(sleep-for 2)
(/ 10 0) ; divide by zero signals an error
(message "This will never evaluate")
(sleep-for 2)
(setq some-var 5)))
(message "Here are the unwind forms that will always evaluate")
(sleep-for 2)
(setq some-var 10)
(setq another-var "puppies")
(message "All done!"))
with-demoted-errors
仅适用于24.4
@Dan很好地描述了如何将错误转化为消息。您也可以使用来做任何想要的错误处理
condition-case
。另一个选择是使用
unwind-protect
。
我会坚持下去condition-case
,没有任何理由。
这应该始终确保您对键定义进行评估,无论在内部发生了什么condition-case
。任何错误都会存储在其中init-error
。
(defvar init-error nil
"The error which happened.")
(condition-case the-error
(progn
;; Do the dangerous stuff here.
(require 'what-I-want))
(error
;; This is only evaluated if there's an error.
(setq init-error the-error)))
;;; Do the safe stuff here.
(define-key uncrippling-map "\C-h" 'help!)
然后,再次抛出错误。有几种方法可以做到这一点,这是一种。
;;; Throw the error again here.
(when init-error
(funcall #'signal (car init-error) (cdr init-error)))
unwind-protect
执行您在其营救子句中放置的任何代码后,都会立即引发该错误。就像finally
Java 之类的语言,而不是catch
。
其他答案已经很好地涵盖了低级错误处理功能,在这种情况下将很有用。可以提供帮助的另一种方法是模块化。例如,我将初始化文件分为几个不同的文件(provide
适当时使用),然后使用此函数而不是加载它们require
:
(defun my/require-softly (feature &optional filename)
"As `require', but instead of an error just print a message.
If there is an error, its message will be included in the message
printed.
Like `require', the return value will be FEATURE if the load was
successful (or unnecessary) and nil if not."
(condition-case err
(require feature filename)
(error (message "Error loading %s: \"%s\""
(if filename (format "%s (%s)" feature filename) feature)
(error-message-string err))
nil)))
以这种方式加载文件时出现错误仍会打印一条消息,但不会阻止在文件中实际发生错误的地方执行任何操作。
当然,此函数与包裹require
调用并没有什么不同with-demoted-errors
(我在不知道之前就写了它with-demoted-errors
),但是重要的一点是,它实际上可以实现类似Dan的组合,with-demoted-errors
而unwind-protect
无需包裹(可能很长)代码块。
eval-buffer
。感谢您发布。
with-demoted-errors
。您可以向它添加一个字符串参数,例如"LOOK OVER HERE!!! %s"
,这样就不太可能错过消息缓冲区中的错误。