Fehler in Emacs Lisp erneut auslösen

9

Ich muss eine Funktion aufrufen und nur dann eine Bereinigung durchführen , wenn die Funktion fehlschlägt, und dann den Fehler neu starten. Hier ist der Pseudocode:

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

Antworten:

10

Übrigens kann eine alternative Option so etwas sein wie:

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

Der Vorteil besteht darin, dass Sie vermeiden, den Fehler abzufangen und erneut zu werfen. Dies bedeutet beispielsweise, dass der Debugger Ihnen die richtige Rückverfolgung anzeigt (diejenige, die der tatsächlichen Fehlerquelle entspricht, und nicht diejenige, die dem erneuten Auslösen des Fehlers einer anderen Person entspricht ).

Ein weiterer Unterschied besteht darin, dass cleanupnicht nur bei einem Fehler aufgerufen wird, sondern auch, wenn der Code durch einen C-goder einen Aufruf von unterbrochen wird throw.

Stefan
quelle
1
Vielen Dank. Warum nicht condition-casefangen keyboard-quit?
Elena
3
Weil es kein Fehler ist (dh sein Signal quit, hat nicht errorunter seinen Eltern). IOW Sie van fangen sie auch mit , condition-caseaber dafür müssen Sie setzen quitmit zusammen error. Natürlich wird das den "Wurf" -Fall immer noch nicht behandeln.
Stefan
13

Sie suchen signal:

(condition-case err
    (call-function)
  (error
   (cleanup)
   (signal (car err) (cdr err)))) ; reraise `err'
npostavs
quelle
Ich hatte überlegt signal, aber sein Prototyp ist (signal ERROR-SYMBOL DATA)nicht (signal ERROR).
Elena
@Elena: richtig sorry, du hast es mit carund auseinander gezogen cdr. Antwort aktualisiert.
npostavs