以编程方式从错误中获取回溯


12

如果在Emacs Lisp代码中以表示错误,并且debug-on-errort,则我将获得一个回溯缓冲区,可以很容易地找出发生错误的位置。但是,对于异步处理来自网络的响应时发生的错误,弹出回溯缓冲区会很烦人,所以我宁愿捕获错误condition-case并记录下来。

因此,当我处理中的错误时condition-case,是否有办法在错误发生时访问回溯?调用该backtrace函数将获取处理程序内部代码的回溯,这不是我想要的。

(condition-case e
    (do-something-that-might-fail)
  (error
    (message "%s"
             ;; This gets the wrong backtrace!
             (with-temp-buffer
               (let ((standard-output (current-buffer)))
                 (backtrace)
                 (buffer-string))))))

1
我的magithub-error功能与我认为的功能类似,但是我现在不在电脑旁。可能会有所帮助。
肖恩·艾瑞德

1
对于以类似方式管理堆栈的任何语言,这都是一个普遍的问题。处理该错误的一种方法是发出已附加堆栈信息的错误信号。即在您的情况下,您将do-something-that-might-fail生成堆栈跟踪并将其附加到它引起的错误上。
wvxvw 16-10-28

1
debbugs.gnu.org/cgi/bugreport.cgi?bug=24617#8有一个建议(我自己还没有尝试过)
npostavs,2016年

Answers:


1

最简单的方法是在发生错误的环境中创建自己的调试器。像这样:

(defun my-debugger (&rest debugger-args)
  (message "BACKTRACE: %s"
           (with-temp-buffer
             (let ((standard-output (current-buffer)))
               (backtrace)
               (buffer-string)))))

(let ((debugger #'my-debugger))
  (foobar)) ; Runs a function with no definition!

let环境my-debugger在其中的代码持续时间内使用此自定义调试器功能,因此,如果遇到未处理的错误,则将运行“调试器”,它实际上只是打印出消息。该调试器在发生错误的环境中运行,因此您的回溯将告诉您发生了什么。

注意:此代码有两个(可解决)问题,我留给您解决。首先,您可能希望剥离前几个堆栈框架,因为它们与的调用有关backtrace。其次,您还会收到一条消息,指出错误(例如,在上述情况下,“ let:Symbol的函数定义为void:foobar”)。都不是大问题,但是我不想弄乱我的反应。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.