Relanzando un error en Emacs Lisp

9

Necesito llamar a una función y realizar una limpieza solo si la función falla, y luego reiniciar el error. Aquí está el pseudocódigo:

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

Respuestas:

10

Por cierto, una opción alternativa puede ser algo como:

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

La ventaja es que evita atrapar y volver a lanzar el error, lo que significa, por ejemplo, que el depurador le mostrará la traza inversa correcta (la que corresponde a la fuente real del error, en lugar de la que corresponde a que usted vuelva a lanzar el error de otra persona) )

Otra diferencia es que cleanupse llamará no solo en caso de error, sino también si el código se interrumpe por una C-go una llamada a throw.

Stefan
fuente
1
Gracias. ¿Por qué no condition-caseatrapar keyboard-quit?
Elena
3
Porque no es un error (es decir, su señal, quitno tiene errorentre sus padres). IOW con el que también puedes atraparlo, condition-casepero para eso debes llevarlo quitbien error. Por supuesto, eso todavía no manejará el caso de "lanzamiento".
Stefan
13

Estas buscando signal:

(condition-case err
    (call-function)
  (error
   (cleanup)
   (signal (car err) (cdr err)))) ; reraise `err'
npostavs
fuente
Lo había considerado signal, pero su prototipo (signal ERROR-SYMBOL DATA)no lo es (signal ERROR).
Elena
@ Elena: lo siento, lo has separado con cary cdr. Respuesta actualizada
npostavs