10.8 Errors

Errors are abnormalities that are detected during a programs execution. Errors may be caused by bugs in XPCE, bugs in the application program and finally by the application user making errors in operating the application (e.g. specifying a protected file).

Errors may also be discriminated according to their `seriousness': If a certain font cannot be found it can easily be substituted by another. If a method expects an integer argument but the actual argument is a graphical object it is impossible to carry-out the operation. In such cases XPCE will normally trap the tracer. If the user decides to continue execution the method will return failure to its caller. Finally, some problems are categorised as `fatal'. When such a problem is encountered XPCE does not know how execution can be continued.

All errors (except for some that may result from XPCE bugs during the boot phase of XPCE) are represented by an error object. An error object has the following properties:

The online manual ``Errors Browser'' may be used to examine the defined errors; change attributes of errors and get precise description of errors.

10.8.1 Handling errors in the application

Sometimes the application wants to anticipate on certain errors. Explicit testing of all conditions is a cumbersome solution to this problem. Therefore XPCE allows catching of errors by the application.

There are two mechanism available to do this. Regardless of the `error<-feedback' type of the error, all except fatal errors can be silenced using pce_catch_error/2:

pce_catch_error(+ErrorSpec, :Goal)
Run Goal like once/1. It an error matching ErrorSpec is raised, this error is not reported, but stored in `@pce<-last_error'. ErrorSpec is the <-id of an error, a chain holding error-ids or @default. The latter implies none but fatal errors are reported.

The example below silently ignores errors from creating a backup of File. Note that the call does fail if backup raises an error.

        ...,
        pce_catch_error(backup_file, send(File, backup)),
        ...

If the <-feedback of the error is throw and the error is not silenced with pce_catch_error/2 it is mapped to a Prolog exception of the form

error(pce(Id, ContextArgs), Goal)

For example:

?- catch(send(@pce, foobar), E, true).

E = error(pce(no_behaviour, [@pce/pce,  (->), foobar]),
          send(@pce/pce, foobar))

10.8.2 Raising errors

The application programmer may define new (application specific) errors. The error object is a normal XPCE object and may thus be created using new/2. An error is raised by invoking `object->error'. The example below illustrates this:

:- new(_, error(no_user,
                '%N: Unknown user: %s',
                warning, report)).

        ...,
        (   get(UserDatabase, user, Name)
        ->  ...
        ;   send(UserDatabase, error, no_user, Name)
        ),
        ...

Note that the names of errors should be unique. It is advised to reuse existing error-id's if possible.

10.8.3 Repairable errors

On trapping certain `repairable` errors, XPCE will first raise an exception. Exceptions may be trapped by an exception handler which may solve the problem. If the exception-handler fails to solve the problem, XPCE will raise an error. See section 10.8.

Exceptions are raised by invoking `@pce->exception: id, arg ...'. Exception handlers are registered in the sheet `@pce->exception_handlers', which maps an exception-id onto a code object that handles the exception. The following illustrates this:

1 ?- [user].
|: add_user(Name) :- write(Name), nl.
^D

2 ?- send(@pce?exception_handlers, value,
          no_user,
          message(@prolog, add_user, @arg1)).

3 ?- send(@pce, exception, no_user, fred).
fred

The context arguments passed with an exception are defined by the code raising the exception. The currently defined exceptions are listed below. See also the online manual: `pce->exception' and `pce<-exception_handlers'.