setup_call_cleanup/3, which is currently being considered for inclusion in the Prolog ISO standard and provided by an increasing number of implementations, lets us ensure that resources are correctly freed after an exception is thrown.
A typical invocation is:
setup_call_cleanup(open(File, Mode, Stream), process_file(File), close(Stream))
Note that an exception or interrupt may even occur immediately after
open/3 is called in this case. For this reason, the
Setup phase is performed atomically. In Prolog systems that only provide
call_cleanup/2, this is much harder to express.