If, however, an exception is thrown during the execution of Goal (either by an error condition in a built-in predicate, or by an invocation of throw/1), and the exception term unifies with Catcher, then the execution of Goal is undone, and Recovery is called instead. In this case, catch(Goal,Catcher,Recovery) is equivalent to call(Recovery). Note that exceptions within Recovery are NOT caught by this catch!
If Goal terminates with an exception, and the exception term does NOT unify with Catcher, then the exception is passed on, allowing an ancestor catch/3 to catch it. The innermost invocation of catch/3 whose Catcher argument matches the exception will catch it.
NOTE: block/3 is a deprecated alias for catch/3, and behaves identically. exit_block/1 is a deprecated alias for throw/1, and behaves identically.
% success, failure and backtracking are not affected by the catch: ?- catch(X is 3+4, T, writeln(recover(T))). X = 7 T = T Yes (0.00s cpu) ?- catch(8 is 3+4, T, writeln(recover(T))). No (0.00s cpu) ?- catch(member(X,[1,2]), T, writeln(recover(T))). X = 1 T = T Yes (0.00s cpu, solution 1, maybe more) ? ; X = 2 T = T Yes (0.00s cpu, solution 2) % A variable Catcher catches all throws ?- catch(throw(hello), T, writeln(recover(T))). recover(hello) T = hello Yes (0.00s cpu) % An instantiated Catcher catches only matching throws ?- catch(throw(hello), hello, writeln(recovered)). recovered Yes (0.00s cpu) ?- catch(throw(hello), world, writeln(recovered)). uncaught exception in throw(hello) Abort % A partially instantiated Catcher catches only matching throws ?- catch(throw(hello(world)), hello(Who), writeln(recovered(Who))). recovered(world) Yes (0.00s cpu) ?- catch(throw(hi(world)), hello(Who), writeln(recovered(Who))). uncaught exception in throw(hi(world)) Yes (0.00s cpu) % ECLiPSe's error handlers usually execute throw(abort) % and therefore can be caught with a catch: ?- catch(X is 1//0, T, writeln(recover(T))). arithmetic exception in //(1, 0, X) recover(abort) X = X T = abort Yes (0.01s cpu) % Executing a recovery action AND passing the exception on: ?- catch(throw(hello), T, (writeln(caught(T)), throw(T))). caught(hello) uncaught exception in throw(hello) Abort