11.7.3.4 错误符号与条件名称

当你抛出一个错误时,需要指定一个 错误符号(error symbol),用来表明你所指的错误类型。每个错误有且仅有一个错误符号对其进行分类,这是 Emacs Lisp 语言中最精细的错误分类方式。

这些精细的分类又被归入范围更广的 错误条件(error conditions) 层级体系中,由 条件名称(condition names) 标识。其中最精细的分类就是错误符号本身:每个错误符号同时也是一个条件名称。同时也存在覆盖范围更广的条件名称,最顶层的条件名称是 error,它包含所有类型的错误(但不包括 quit)。 因此,每个错误都拥有一个或多个条件名称:error、该错误自身的符号(如果它与 error 不同),以及可能存在的一些中间分类名称。

Function: define-error name message &optional parent

若要将一个符号定义为错误符号,必须通过 define-error 函数来完成定义 —— 该函数需指定一个父条件(默认值为 error)。这个父条件决定了此类错误所属的条件范畴。父条件的传递闭包集合始终包含错误符号本身,以及符号 error。由于「退出(quitting)」不被视作错误,因此 quit 的父条件集合仅为 (quit)

除父条件外,错误符号还关联有一个 message(消息字符串):当该错误被抛出但未被处理时,此字符串会被打印。若该消息无效,则会使用错误提示语 ‘peculiar error’(异常错误)。See Definition of signal

在内部实现中,父条件集合被存储在错误符号的 error-conditions 属性中,而错误消息则存储在错误符号的 error-message 属性中。

以下是定义新错误符号 new-error 的方式:

(define-error 'new-error "A new error" 'my-own-errors)

该错误拥有多个条件名称:最细分的类型 new-error;我们假定的范围更广的分类 my-own-errors;以及 my-own-errors 所继承的所有条件,其中应当包含范围最广的 error

错误字符串应以大写字母开头,但不应以句号结尾。这是为了与 Emacs 其他部分保持一致。

显然,Emacs 自身永远不会主动抛出 new-error;只有在你的代码中显式调用 signal(see Definition of signal)才能触发该错误:

(signal 'new-error '(x y))
     error→ A new error: x, y

可以通过该错误的任意一个条件名称来捕获它。 下面这个示例会处理 new-error 以及属于 my-own-errors 类别的其他所有错误:

(condition-case foo
    (bar nil t)
  (my-own-errors nil))

错误的主要分类方式是通过条件名称(condition names) — 也就是用于将错误与处理函数匹配的名称。错误符号仅作为一种便捷方式,用来指定对应的错误消息和条件名称列表。如果给 signal 传入一长串条件名称,而不是一个错误符号,会非常繁琐。

相反,如果只使用错误符号、不使用条件名称,会严重削弱 condition-case 的能力。条件名称让你在编写错误处理函数时,可以按不同粒度对错误进行分类。如果只使用错误符号,就只能使用最细粒度的分类,无法进行更粗粒度的归类。

有关主要错误符号及其条件的列表,see Standard Errors


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike