Repetindo um erro no Emacs Lisp

9

Preciso chamar uma função e executar uma limpeza somente se a função falhar e, em seguida, reiniciar o erro. Aqui está o pseudo-código:

(condition-case err
    (call-function)
  (error
   (cleanup)
   ;; how do I raise `err`?
   ))
Elena
fonte

Respostas:

10

BTW, uma opção alternativa pode ser algo como:

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

A vantagem é que você evita capturar e repetir o erro, o que significa, por exemplo, que o depurador mostrará o backtrace correto (aquele que corresponde à fonte real do erro, em vez daquele que corresponde a você repetir o erro de outra pessoa) )

Outra diferença é que cleanupserá chamado não apenas por erro, mas também se o código for interrompido por uma C-gou uma chamada para throw.

Stefan
fonte
11
Obrigado. Por que não condition-casepegaria keyboard-quit?
Elena
3
Porque não é um erro (ou seja, seu sinal, quitnão tem errorentre seus pais). IOW você van também pegá-lo, condition-casemas para isso você precisa colocar quitjunto error. Obviamente, isso ainda não vai lidar com o caso 'throw'.
275 Stefan
13

Você está procurando signal:

(condition-case err
    (call-function)
  (error
   (cleanup)
   (signal (car err) (cdr err)))) ; reraise `err'
npostavs
fonte
Eu tinha considerado signal, mas seu protótipo (signal ERROR-SYMBOL DATA)não é (signal ERROR).
Elena
@ Elena: desculpe, você o separou com care cdr. Resposta atualizada.
npostavs 04/07/2015