12

I need to call a function and perform a cleanup only if the function fails, and then relaunch the error. Here is the pseudo-code:

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

2 Answers 2

12

BTW, an alternative option can be something like:

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

The advantage is that you avoid catching&rethrowing the error, which means for example that the debugger will show you the right backtrace (the one that corresponds to the actual source of the error, rather than the one that corresponds to you re-throwing someone else's error).

Another differences is that cleanup will be called not only upon error but also if the code is interrupted by a C-g or a call to throw.

3
  • 1
    Thanks. Why wouldn't condition-case catch keyboard-quit?
    – Eleno
    Commented Jul 8, 2015 at 7:02
  • 3
    Because it's not an error (i.e. its signal, quit, does not have error among its parents). IOW you van also catch it with condition-case but for that you need to put quit along with error. Of course, that still won't handle the `throw' case.
    – Stefan
    Commented Jul 8, 2015 at 13:41
  • +1 For many common cases, unwind-protect is a neater alternative to fine-grained exception handling with condition-case.
    – mindthief
    Commented Nov 23, 2020 at 3:02
17

You're looking for signal:

(condition-case err
    (call-function)
  (error
   (cleanup)
   (signal (car err) (cdr err)))) ; reraise `err'
2
  • I had considered signal, but its prototype is (signal ERROR-SYMBOL DATA), not (signal ERROR).
    – Eleno
    Commented Jul 4, 2015 at 15:40
  • @Elena: right sorry, you have pull it apart with car and cdr. Answer updated.
    – npostavs
    Commented Jul 4, 2015 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.