Исправление ошибки в Emacs Lisp

9

Мне нужно вызвать функцию и выполнить очистку только в случае сбоя функции, а затем повторно запустить ошибку. Вот псевдокод:

(condition-case err
    (call-function)
  (error
   (cleanup)
   ;; how do I raise `err`?
   ))
Елена
источник

Ответы:

10

Кстати, альтернативный вариант может быть что-то вроде:

(let ((error t))
  (unwind-protect
      (prog1 (call-function)
        (setq error nil))
    (when error (cleanup))))

Преимущество состоит в том, что вы избегаете перехвата и повторного выброса ошибки, что означает, например, что отладчик покажет вам правильную обратную трассировку (ту, которая соответствует фактическому источнику ошибки, а не ту, которая соответствует повторной выдаче чужой ошибки). ).

Другое отличие состоит в том, что cleanupон будет вызван не только при ошибке, но также и в том случае, если код прерывается C-gвызовом или throw.

Стефан
источник
1
Спасибо. Почему бы не condition-caseпоймать keyboard-quit?
Елена
3
Потому что это не ошибка (т. Е. Его сигнал, quitне имеет errorсреди своих родителей). IOW вы также поймать его, condition-caseно для этого нужно положить quitвместе error. Конечно, это все равно не справится с делом `throw '.
Стефан
13

Вы ищете signal:

(condition-case err
    (call-function)
  (error
   (cleanup)
   (signal (car err) (cdr err)))) ; reraise `err'
npostavs
источник
Я считал signal, но его прототип есть (signal ERROR-SYMBOL DATA), нет (signal ERROR).
Елена
@Elena: огорчился, вы должны вытащить его на части с carи cdr. Ответ обновлен.
npostavs