dynamic-wind + error pasted by DerGuteMoritz on Thu Oct 29 17:41:51 2020

(dynamic-wind
    (lambda ()
      (print* "before\n"))
    (lambda ()
      (print* "within\n")
      (error 'boom))
    (lambda ()
      (print* "after\n")))

csi 4.13.0 pasted by DerGuteMoritz on Thu Oct 29 17:44:08 2020

$ csi -s repro2.scm 
before
within

Error: boom

	Call history:

	<syntax>	  (print* "before\n")
	<syntax>	  (lambda () (print* "within\n") (error (quote boom)))
	<syntax>	  (##core#lambda () (print* "within\n") (error (quote boom)))
	<syntax>	  (##core#begin (print* "within\n") (error (quote boom)))
	<syntax>	  (print* "within\n")
	<syntax>	  (error (quote boom))
	<syntax>	  (quote boom)
	<syntax>	  (##core#quote boom)
	<syntax>	  (lambda () (print* "after\n"))
	<syntax>	  (##core#lambda () (print* "after\n"))
	<syntax>	  (##core#begin (print* "after\n"))
	<syntax>	  (print* "after\n")
	<eval>	  (dynamic-wind (lambda () (print* "before\n")) (lambda () (print* "within\n") (error (quote boom))) (...
	<eval>	  (print* "before\n")
	<eval>	  (print* "within\n")
	<eval>	  (error (quote boom))	<--

csc 4.13.0 pasted by DerGuteMoritz on Thu Oct 29 17:45:06 2020

$ csc repro2.scm 
$ ./repro2 
before
within

Error: boom

	Call history:

	repro2.scm:1: dynamic-wind	  
	repro2.scm:3: print*	  
	repro2.scm:5: print*	  
	repro2.scm:6: error	  	<--

csi 5.2.0 pasted by DerGuteMoritz on Thu Oct 29 17:46:48 2020

$ csi -s repro2.scm 
before
within

Error: boom

	Call history:

	<syntax>	  (print* "before\n")
	<syntax>	  (lambda () (print* "within\n") (error (quote boom)))
	<syntax>	  (##core#lambda () (print* "within\n") (error (quote boom)))
	<syntax>	  (##core#begin (print* "within\n") (error (quote boom)))
	<syntax>	  (print* "within\n")
	<syntax>	  (error (quote boom))
	<syntax>	  (quote boom)
	<syntax>	  (##core#quote boom)
	<syntax>	  (lambda () (print* "after\n"))
	<syntax>	  (##core#lambda () (print* "after\n"))
	<syntax>	  (##core#begin (print* "after\n"))
	<syntax>	  (print* "after\n")
	<eval>	  (dynamic-wind (lambda () (print* "before\n")) (lambda () (print* "within\n") (error (quote boom))) (...
	<eval>	  (print* "before\n")
	<eval>	  (print* "within\n")
	<eval>	  (error (quote boom))	<--

unwind-protect, but not as we know it pasted by wasamasa on Thu Oct 29 18:42:56 2020

(import (chicken condition))
(import (srfi 18))

(define (unwind-protect before-thunk body-thunk after-thunk)
  (handle-exceptions e
    (raise e)
    (dynamic-wind
        before-thunk
        body-thunk
        unwind-thunk)))

(unwind-protect
 (lambda () #f)
 (lambda ()
   (print* "within\n")
   (error 'boom))
 (lambda ()
   (print* "after\n")))

alternative suggestion: finally added by DerGuteMoritz on Fri Oct 30 12:03:23 2020

;; The first thunk passed to `finally` would be called on normal exit
;; and on exit via condition but not when escaping via a
;; continuation. For dealing with the latter, too, you'd need to use
;; dynamic-wind + handle-exceptions instead.
(define (dwim-with-input-file path proc)
  (let ((port (open-input-file path)))
    (finally (lambda (close-input-port port))
             (lambda () (proc port)))))