This section discusses PL_exception, PL_throw and PL_raise_exception, the interface functions to detect and generate Prolog exceptions from C-code. PL_throw and PL_raise_exception from the C-interface to raise an exception from foreign code. PL_throw exploits the C-function longjmp() to return immediately to the innermost PL_next_solution. PL_raise_exception registers the exception term and returns FALSE. If a foreign predicate returns FALSE, while and exception-term is registered a Prolog exception will be raised by the virtual machine.
Calling these functions outside the context of a function implementing a foreign predicate results in undefined behaviour.
PL_exception may be used after a call to PL_next_solution fails, and returns a term reference to an exception term if an exception was raised, and 0 otherwise.
If a C-function, implementing a predicate calls Prolog and detects an exception using PL_exception, it can handle this exception, or return with the exception. Some caution is required though. It is not allowed to call PL_close_query or PL_discard_foreign_frame afterwards, as this will invalidate the exception term. Below is the code that calls a Prolog defined arithmetic function (see arithmethic_function1).
If PL_next_solution succeeds, the result is analysed and translated to a number, after which the query is closed and all Prolog data created after PL_open_foreign_frame is destroyed. On the other hand, if PL_next_solution fails and if an exception was raised, just pass it. Otherwise generate an exception (PL_error is an internal call for building the standard error terms and calling PL_raise_exception). After this, the Prolog environment should be discarded using PL_cut_query and PL_close_foreign_frame to avoid invalidating the exception term.
intPL_throwterm_t exception Similar to PL_raise_exception, but returns using the C longjmp() function to the innermost PL_next_solution.
term_tPL_exceptionqid_t qid If PL_next_solution fails, this can be due to normal failure of the Prolog call, or because an exception was raised using throw1. This function returns a handle to the exception term if an exception was raised, or 0 if the Prolog goal simply failed.3.4.