The predicate throw/1
takes a single argument, the exception term, and the ISO
standard stipulates that the exception term be of the form error(Formal,
Context)
with:
Thus, constructing an error term and throwing it might take this form (although you would not use the illustrative explicit naming given here; instead composing the exception term directly in a one-liner):
Exception = error(Formal, Context), Context = ... some local convention ..., Formal = type_error(ValidType, Culprit), % for "type error" for example ValidType = integer, % valid atoms are listed in the ISO standard Culprit = ... some value ..., throw(Exception)
Note that the ISO standard formal term expresses what should be the case or what is the expected correct state, and not what is the problem. For example:
instantiation_error
: The
problem is not that there is an unwanted instantiation, but that the
correct state is the one with an instantiated variable.
uninstantiation_error(Culprit)
: The problem is not that
there is lack of instantiation, but that the correct state is the one
which
Culprit (or one of its subterms) is more uninstantiated than
is the case.
type_error(compound,[])
. The problem is
not that []
is (erroneously) a compound term,
but that a compound term is expected and []
does not belong to that class.
User predicates are free to choose the structure of their exception terms (i.e., they can define their own conventions) but should adhere to the ISO standard if possible, in particular for libraries.
Notably, exceptions of the shape error(Formal,Context)
are recognised by the development tools and therefore expressing
unexpected situations using these exceptions improves the debugging
experience.
In SWI-Prolog, the second argument of the exception term, i.e., the
Context argument, is generally of the form
context(Location, Message)
, where:
library(prolog_stack)
library. This library recognises
uncaught errors or errors caught by catch_with_backtrace/3
and fills the
Location argument with a backtrace.
ISO standard exceptions can be thrown via the predicates exported
from library(error)
. Termwise, these predicates look
exactly like the
Formal of the ISO standard error term they throw: