11.7.3.1 如何发出错误信号

发出(signaling) 错误,指的是启动错误处理流程。错误处理通常会中止正在运行的程序的全部或部分,并返回到预先设置好用于处理错误的位置(see 如何处理错误)。这里我们介绍如何主动发出错误。

大多数错误是在你调用的 Lisp 基本函数内部自动发出的,比如你试图对一个整数取 CAR,或者在缓冲区末尾尝试向前移动字符时。你也可以使用函数 errorsignal 显式地发出错误。

当用户按下 C-g 时触发的退出(Quitting),不算作错误,但其处理方式与错误几乎相同。See Quitting

所有错误都会以这样或那样的方式指定一条错误消息。消息应当说明哪里出了问题(例如 “File does not exist”),而非事情 “应该是怎样的”(例如 “File must exist”)。Emacs Lisp 中的约定是:错误消息应以大写字母开头,但不应以任何形式的标点符号结尾。

Function: error format-string &rest args

该函数会触发一个错误,其错误消息是通过将 format-message(see 格式化字符串)作用于 format-string(格式字符串)和 args(参数列表)构建而成。

以下示例展示了 error 的典型用法:

(error "That is an error -- try something else")
     error→ That is an error -- try something else

(error "Invalid name `%s'" "A%%B")
     error→ Invalid name ‘A%%B’

error 函数的实现逻辑是调用 signal 并传入两个参数:错误符号 error,以及一个包含 format-message 返回字符串的列表。

格式字符串中的重音符和撇号,通常会被转换为配对的弯引号,例如 "Missing `%s'" 可能会被转换为 "Missing ‘foo’".。关于如何调整或禁止这种转换方式,详见 See Text Quoting Style

警告: 如果你希望原封不动地使用自定义字符串作为错误消息,不要直接编写 (error string)。若 string 中包含 ‘%’、‘`’ 或 ‘'’,该字符串可能会被重新格式化,从而产生不符合预期的结果。正确的写法是使用 (error "% s" string)

noninteractive 的值为非 nil 时(see Batch Mode),若触发的错误没有对应的处理函数,该函数会终止 Emacs 进程。

Function: signal error-symbol data

该函数会触发一个以 error-symbol(错误符号)命名的错误。参数 data 是一个列表,包含与该错误场景相关的其他 Lisp 对象。

参数 error-symbol 必须是一个 错误符号(error symbol) — 即通过 define-error 定义的符号。Emacs Lisp 正是通过这种方式对不同类型的错误进行分类。关于错误符号、错误条件及条件名的详细说明,see 错误符号与条件名称

若该错误未被处理,则这两个参数会被用于打印错误消息。通常情况下,错误消息由 error-symbolerror-message 属性提供。若 data 为非 nil 值,则消息末尾会追加一个冒号,并跟上 data 中未经求值的元素组成的逗号分隔列表。对于 error 类型的错误,其错误消息为 dataCAR 部分(该部分必须是字符串)。file-error 的子类别会被特殊处理。

data 列表中对象的数量和含义由 error-symbol 决定。例如,对于 wrong-type-argument 错误,列表中应包含两个对象:一个用于描述期望类型的断言(谓词),以及一个不符合该类型的对象。

error-symbol(错误符号)和 data(附加数据)均可被处理该错误的所有错误处理函数访问:condition-case 会将一个局部变量绑定为形如 (error-symbol . data) 的列表(see 编写处理错误的代码)。

signal 函数永远不会返回。 若 error-symbol 对应的错误没有处理函数,且 noninteractive 的值为非 nil(see Batch Mode),该函数最终会终止 Emacs 进程。

(signal 'wrong-number-of-arguments '(x y))
     error→ Wrong number of arguments: x, y

(signal 'no-such-error '("My unknown error condition"))
     error→ peculiar error: "My unknown error condition"
Function: user-error format-string &rest args

该函数的行为与 error 完全一致,唯一区别是它使用错误符号 user-error 而非 error。顾名思义,该函数用于报告用户操作引发的错误,而非代码本身的错误。例如,若你尝试使用 Info-history-back 命令(快捷键 l)回退到 Info 浏览历史的起始位置之前,Emacs 会触发一个 user-error 错误。这类错误不会触发调试器,即便 debug-on-error 的值为非 nil 也是如此。 See 发生错误时进入调试器

Common Lisp 注意: Emacs Lisp 中没有类似于 Common Lisp 里可继续错误的概念。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike