The exception handling mechanism implemented is based on the predicates catch/3 and throw/1, it follows the definition of exception handling in the ISO Prolog standard. The principle of exceptions is that if an error occurs an exception is thrown. The exception to throw is a Prolog structure (with 2 arguments). At different places in a program there can be catch statements that are capable of catching exceptions. A catch/3 statement gives the ability to write local error handling code that does something useful like warning the user by displaying a dialog window with a message or closing a resource like an open file, etc...
| Example | |
| catch( test1(X), _, (true) ) | The goal to prove becomes test1(x) |
During normal execution a catch statement is treated as the call statement, i.e. the first argument of both predicates becomes a goal to prove. During failing or exiting of that same goal both predicates respond the same.
An exception structure is matched against the second argument of catch/3 to determine if it may handle the exception. If the match succeeds then the recovery goal of catch/3 is executed (the third argument). If the match fails then the Prolog inference engine continues the search for a catch/3 statement that can catch the exception. In the example above is the second argument an anonymous variable, this implies that it catches all exceptions.
If no catch/3 statement is present that can catch the thrown exception then the proving of the current goal stops and an error message is displayed in the message window of the Trinc-Prolog IDE.
Consider the following Prolog goal, it will cause an exception because it will divide 2 by 0.
| X is 2 / 0. | the following exception will be thrown: error(evaluation_error(zero_divisor), 0) |
To catch this exception the following statements can be used:
| catch( X is 2 / 0, _, true ). | the exception thrown will be catched and the value of the
anonymous variable will be: _ = error(evaluation_error(zero_divisor), 0) |
| catch( X is 2 / 0, error(X, Y), true). | The exception thrown will be catched, the values of the
variables X and Y will be: X = evaluation_error(zero_divisor) Y = 0 |
| catch( X is 2 / 0, error(evaluation_error(X), Y), true). | The values of the variables X and Y will be: X = zero_divisor Y = 0 |
It is also possible that the exception thrown is not catched, for instance:
| catch( X is 2 / 0, error(evaluation_error(zero), Y), true). | The exception thrown does not match with the second argument of catch/3 |