/usr/lib/swi-prolog/doc/Manual/exception.html is in swi-prolog-nox 5.10.4-3ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>SWI-Prolog 5.11.18 Reference Manual: Section 4.9</TITLE><LINK REL=home HREF="index.html">
<LINK REL=contents HREF="Contents.html">
<LINK REL=index HREF="DocIndex.html">
<LINK REL=summary HREF="summary.html">
<LINK REL=previous HREF="metacall.html">
<LINK REL=next HREF="signal.html">
<STYLE type="text/css">
/* Style sheet for SWI-Prolog latex2html
*/
dd.defbody
{ margin-bottom: 1em;
}
dt.pubdef
{ background-color: #c5e1ff;
}
dt.multidef
{ background-color: #c8ffc7;
}
.bib dd
{ margin-bottom: 1em;
}
.bib dt
{ float: left;
margin-right: 1.3ex;
}
pre.code
{ margin-left: 1.5em;
margin-right: 1.5em;
border: 1px dotted;
padding-top: 5px;
padding-left: 5px;
padding-bottom: 5px;
background-color: #f8f8f8;
}
div.navigate
{ text-align: center;
background-color: #f0f0f0;
border: 1px dotted;
padding: 5px;
}
div.title
{ text-align: center;
padding-bottom: 1em;
font-size: 200%;
font-weight: bold;
}
div.author
{ text-align: center;
font-style: italic;
}
div.abstract
{ margin-top: 2em;
background-color: #f0f0f0;
border: 1px dotted;
padding: 5px;
margin-left: 10%; margin-right:10%;
}
div.abstract-title
{ text-align: center;
padding: 5px;
font-size: 120%;
font-weight: bold;
}
div.toc-h1
{ font-size: 200%;
font-weight: bold;
}
div.toc-h2
{ font-size: 120%;
font-weight: bold;
margin-left: 2em;
}
div.toc-h3
{ font-size: 100%;
font-weight: bold;
margin-left: 4em;
}
div.toc-h4
{ font-size: 100%;
margin-left: 6em;
}
span.sec-nr
{
}
span.sec-title
{
}
span.pred-ext
{ font-weight: bold;
}
span.pred-tag
{ float: right;
padding-top: 0.2em;
font-size: 80%;
font-style: italic;
color: #202020;
}
/* Footnotes */
sup.fn { color: blue; text-decoration: underline; }
span.fn-text { display: none; }
sup.fn span {display: none;}
sup:hover span
{ display: block !important;
position: absolute; top: auto; left: auto; width: 80%;
color: #000; background: white;
border: 2px solid;
padding: 5px; margin: 10px; z-index: 100;
font-size: smaller;
}
</STYLE>
</HEAD>
<BODY BGCOLOR="white">
<DIV class="navigate"><A class="nav" href="index.html"><IMG SRC="home.gif" BORDER=0 ALT="Home"></A>
<A class="nav" href="Contents.html"><IMG SRC="index.gif" BORDER=0 ALT="Contents"></A>
<A class="nav" href="DocIndex.html"><IMG SRC="yellow_pages.gif" BORDER=0 ALT="Index"></A>
<A class="nav" href="summary.html"><IMG SRC="info.gif" BORDER=0 ALT="Summary"></A>
<A class="nav" href="metacall.html"><IMG SRC="prev.gif" BORDER=0 ALT="Previous"></A>
<A class="nav" href="signal.html"><IMG SRC="next.gif" BORDER=0 ALT="Next"></A>
</DIV>
<H2><A NAME="sec:4.9"><SPAN class="sec-nr">4.9</SPAN> <SPAN class="sec-title">ISO
compliant Exception handling</SPAN></A></H2>
<A NAME="sec:exception"></A>
<P>SWI-Prolog defines the predicates <A NAME="idx:catch3:546"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
and <A NAME="idx:throw1:547"></A><A class="pred" href="exception.html#throw/1">throw/1</A>
for ISO compliant raising and catching of exceptions. In the current
implementation (4.0.6), most of the built-in predicates generate
exceptions, but some obscure predicates merely print a message, start
the debugger and fail, which was the normal behaviour before the
introduction of exceptions.
<DL class="latex">
<DT class="pubdef"><span class="pred-tag">[ISO]</span><A NAME="catch/3"><STRONG>catch</STRONG>(<VAR>:Goal,
+Catcher, :Recover</VAR>)</A></DT>
<DD class="defbody">
Behaves as <A NAME="idx:call1:548"></A><A class="pred" href="metacall.html#call/1">call/1</A>
if no exception is raised when executing <VAR>Goal</VAR>. If an
exception is raised using <A NAME="idx:throw1:549"></A><A class="pred" href="exception.html#throw/1">throw/1</A>
while <VAR>Goal</VAR> executes, and the <VAR>Goal</VAR> is the innermost
goal for which <VAR>Catcher</VAR> unifies with the argument of <A NAME="idx:throw1:550"></A><A class="pred" href="exception.html#throw/1">throw/1</A>,
all choice-points generated by <VAR>Goal</VAR> are cut, the system
backtracks to the start of <A NAME="idx:catch3:551"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
while preserving the thrown exception term and <VAR>Recover</VAR> is
called as in <A NAME="idx:call1:552"></A><A class="pred" href="metacall.html#call/1">call/1</A>.
<P>The overhead of calling a goal through <A NAME="idx:catch3:553"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
is very comparable to
<A NAME="idx:call1:554"></A><A class="pred" href="metacall.html#call/1">call/1</A>.
Recovery from an exception is much slower, especially if the
exception-term is large due to the copying thereof.</DD>
<DT class="pubdef"><span class="pred-tag">[ISO]</span><A NAME="throw/1"><STRONG>throw</STRONG>(<VAR>+Exception</VAR>)</A></DT>
<DD class="defbody">
Raise an exception. The system looks for the innermost <A NAME="idx:catch3:555"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
ancestor for which <VAR>Exception</VAR> unifies with the <VAR>Catcher</VAR>
argument of the <A NAME="idx:catch3:556"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
call. See <A NAME="idx:catch3:557"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
for details.
<P>ISO demands <A NAME="idx:throw1:558"></A><A class="pred" href="exception.html#throw/1">throw/1</A>
to make a copy of <VAR>Exception</VAR>, walk up the stack to a <A NAME="idx:catch3:559"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
call, backtrack and try to unify the copy of
<VAR>Exception</VAR> with <VAR>Catcher</VAR>. SWI-Prolog delays making a
copy of
<VAR>Exception</VAR> and backtracking until it actually found a matching
<A NAME="idx:catch3:560"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
goal. The advantage is that we can start the debugger at the first
possible location while preserving the entire exception context if there
is no matching <A NAME="idx:catch3:561"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
goal. This approach can lead to different behaviour if <VAR>Goal</VAR>
and <VAR>Catcher</VAR> of <A NAME="idx:catch3:562"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
call share variables. We assume this to be highly unlikely and could not
think of a scenario where this is useful.<SUP class="fn">33<SPAN class="fn-text">I'd
like to acknowledge Bart Demoen for his clarifications on these matters.</SPAN></SUP>
<P>If an exception is raised in a callback from C (see <A class="sec" href="foreign.html">chapter
9</A>) and not caught in the same call-back, <A class="func" href="foreigninclude.html#PL_next_solution()">PL_next_solution()</A>
fails and the exception context can be retrieved using <A class="func" href="foreigninclude.html#PL_exception()">PL_exception()</A>.
</DD>
</DL>
<H3><A NAME="sec:4.9.1"><SPAN class="sec-nr">4.9.1</SPAN> <SPAN class="sec-title">Debugging
and exceptions</SPAN></A></H3>
<P><A NAME="idx:exceptionsdebugging:563"></A><A NAME="idx:debuggingexceptions:564"></A>Before
the introduction of exceptions in SWI-Prolog a runtime error was handled
by printing an error message, after which the predicate failed. If the
Prolog flag <A class="flag" href="flags.html#flag:debug_on_error">debug_on_error</A>
was in effect (default), the tracer was switched on. The combination of
the error message and trace information is generally sufficient to
locate the error.
<P>With exception handling, things are different. A programmer may wish
to trap an exception using <A NAME="idx:catch3:565"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
to avoid it reaching the user. If the exception is not handled by
user-code, the interactive top-level will trap it to prevent
termination.
<P>If we do not take special precautions, the context information
associated with an unexpected exception (i.e., a programming error) is
lost. Therefore, if an exception is raised, which is not caught using
<A NAME="idx:catch3:566"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
and the top-level is running, the error will be printed, and the system
will enter trace mode.
<P>If the system is in an non-interactive callback from foreign code and
there is no <A NAME="idx:catch3:567"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
active in the current context, it cannot determine whether or not the
exception will be caught by the external routine calling Prolog. It will
then base its behaviour on the Prolog flag
<A class="flag" href="flags.html#flag:debug_on_error">debug_on_error</A>:
<P>
<UL class="latex">
<LI><I>current_prolog_flag(debug_on_error, false)</I><BR>
The exception does not trap the debugger and is returned to the foreign
routine calling Prolog, where it can be accessed using <A class="func" href="foreigninclude.html#PL_exception()">PL_exception()</A>.
This is the default.
<LI><I>current_prolog_flag(debug_on_error, true)</I><BR>
If the exception is not caught by Prolog in the current context, it will
trap the tracer to help analysing the context of the error.
</UL>
<P>While looking for the context in which an exception takes place, it
is advised to switch on debug mode using the predicate <A NAME="idx:debug0:568"></A><A class="pred" href="debugger.html#debug/0">debug/0</A>.
The hook
<A NAME="idx:prologexceptionhook4:569"></A><A class="pred" href="excepthook.html#prolog_exception_hook/4">prolog_exception_hook/4</A>
can be used to add more debugging facilities to exceptions. An example
is the library <CODE>library(http/http_error)</CODE>, generating a full
stack trace on errors in the HTTP server library.
<H3><A NAME="sec:4.9.2"><SPAN class="sec-nr">4.9.2</SPAN> <SPAN class="sec-title">The
exception term</SPAN></A></H3>
<A NAME="sec:exceptterm"></A>
<P>Built-in predicates generates exceptions using a term
<CODE>error(Formal, Context)</CODE>. The first argument is the `formal'
description of the error, specifying the class and generic defined
context information. When applicable, the ISO error-term definition is
used. The second part describes some additional context to help the
programmer while debugging. In its most generic form this is a term of
the form <CODE>context(Name/Arity, Message)</CODE>, where
<VAR>Name</VAR>/<VAR>Arity</VAR> describes the built-in predicate that
raised the error, and <VAR>Message</VAR> provides an additional
description of the error. Any part of this structure may be a variable
if no information was present.
<H3><A NAME="sec:4.9.3"><SPAN class="sec-nr">4.9.3</SPAN> <SPAN class="sec-title">Printing
messages</SPAN></A></H3>
<A NAME="sec:printmsg"></A>
<P>The predicate <A NAME="idx:printmessage2:570"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>
may be used to print a message term in a human readable format. The
other predicates from this section allow the user to refine and extend
the message system. The most common usage of <A NAME="idx:printmessage2:571"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>
is to print error messages from exceptions. The code below prints errors
encountered during the execution of <VAR>Goal</VAR>, without further
propagating the exception and without starting the debugger.
<PRE class="code">
...,
catch(Goal, E,
( print_message(error, E),
fail
)),
...
</PRE>
<P>Another common use is to defined <A NAME="idx:messagehook3:572"></A><A class="pred" href="exception.html#message_hook/3">message_hook/3</A>
for printing messages that are normally <EM>silent</EM>, suppressing
messages, redirecting messages or make something happen in addition to
printing the message.
<DL class="latex">
<DT class="pubdef"><A NAME="print_message/2"><STRONG>print_message</STRONG>(<VAR>+Kind,
+Term</VAR>)</A></DT>
<DD class="defbody">
The predicate <A NAME="idx:printmessage2:573"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>
is used to print messages, notably from exceptions in a human-readable
format. <VAR>Kind</VAR> is one of
<CODE>informational</CODE>, <CODE>banner</CODE>, <CODE>warning</CODE>, <CODE>error</CODE>,
<CODE>help</CODE> or <CODE>silent</CODE>. A human-readable message is
printed to the stream <CODE>user_error</CODE>.
<P><A NAME="idx:silent:574"></A><A NAME="idx:quiet:575"></A>If the
Prolog flag <A class="flag" href="flags.html#flag:verbose">verbose</A>
is <CODE>silent</CODE>, messages with
<VAR>Kind</VAR> <CODE>informational</CODE>, or <CODE>banner</CODE> are
treated as silent. See <STRONG>-q</STRONG>.
<P>This predicate first translates the <VAR>Term</VAR> into a list of
`message lines' (see <A NAME="idx:printmessagelines3:576"></A><A class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</A>
for details). Next it will call the hook <A NAME="idx:messagehook3:577"></A><A class="pred" href="exception.html#message_hook/3">message_hook/3</A>
to allow the user intercepting the message. If <A NAME="idx:messagehook3:578"></A><A class="pred" href="exception.html#message_hook/3">message_hook/3</A>
fails it will print the message unless <VAR>Kind</VAR> is silent.
<P>The <A NAME="idx:printmessage2:579"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>
predicate and its rules are in the file
<CODE><<VAR>plhome</VAR>>/boot/messages.pl</CODE>, which may be
inspected for more information on the error messages and related error
terms. If you need to report errors from your own predicates, we advise
you to stick to the existing error terms if you can; but should you need
to invent new ones, you can define corresponding error messages by
asserting clauses for prolog:message. You will need to declare the
predicate as multifile.
<P>See also <A NAME="idx:messagetostring2:580"></A><A class="pred" href="exception.html#message_to_string/2">message_to_string/2</A>.</DD>
<DT class="pubdef"><A NAME="print_message_lines/3"><STRONG>print_message_lines</STRONG>(<VAR>+Stream,
+Prefix, +Lines</VAR>)</A></DT>
<DD class="defbody">
Print a message (see <A NAME="idx:printmessage2:581"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>)
that has been translated to a list of message elements. The elements of
this list are:
<DL class="latex">
<DT><B><<VAR>Format</VAR>>-<<VAR>Args</VAR>></B></DT>
<DD class="defbody">
Where <VAR>Format</VAR> is an atom and <VAR>Args</VAR> is a list of
format argument. Handed to <A NAME="idx:format3:582"></A><A class="pred" href="format.html#format/3">format/3</A>.
</DD>
<DT><B><CODE>flush</CODE></B></DT>
<DD class="defbody">
If this appears as the last element, <VAR>Stream</VAR> is flushed (see <A NAME="idx:flushoutput1:583"></A><A class="pred" href="chario.html#flush_output/1">flush_output/1</A>)
and no final newline is generated.
</DD>
<DT><B><CODE>at_same_line</CODE></B></DT>
<DD class="defbody">
If this appears as first element, no prefix is printed for the first
line and the line-position is not forced to 0 (see <A NAME="idx:format1:584"></A><A class="pred" href="format.html#format/1">format/1</A>, <CODE>~N</CODE>).
</DD>
<DT><B><<VAR>Format</VAR>></B></DT>
<DD class="defbody">
Handed to <A NAME="idx:format3:585"></A><A class="pred" href="format.html#format/3">format/3</A>
as <CODE>format(Stream, Format, [])</CODE>.
</DD>
<DT><B>nl</B></DT>
<DD class="defbody">
A new line is started and if the message is not complete the <VAR>Prefix</VAR>
is printed too.
</DD>
</DL>
<P>See also <A NAME="idx:printmessage2:586"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>
and <A NAME="idx:messagehook3:587"></A><A class="pred" href="exception.html#message_hook/3">message_hook/3</A>.</DD>
<DT class="pubdef"><A NAME="message_hook/3"><STRONG>message_hook</STRONG>(<VAR>+Term,
+Kind, +Lines</VAR>)</A></DT>
<DD class="defbody">
Hook predicate that may be defined in the module <CODE>user</CODE> to
intercept messages from <A NAME="idx:printmessage2:588"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>. <VAR>Term</VAR>
and <VAR>Kind</VAR> are the same as passed to <A NAME="idx:printmessage2:589"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>. <VAR>Lines</VAR>
is a list of format statements as described with <A NAME="idx:printmessagelines3:590"></A><A class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</A>.
See also
<A NAME="idx:messagetostring2:591"></A><A class="pred" href="exception.html#message_to_string/2">message_to_string/2</A>.
<P>This predicate should be defined dynamic and multifile to allow other
modules defining clauses for it too.</DD>
<DT class="pubdef"><A NAME="message_to_string/2"><STRONG>message_to_string</STRONG>(<VAR>+Term,
-String</VAR>)</A></DT>
<DD class="defbody">
Translates a message-term into a string object (see <A class="sec" href="strings.html">section
4.22</A>). Primarily intended to write messages to Windows in XPCE (see
<A class="sec" href="xpce.html">section 1.5</A>) or other GUI
environments.
</DD>
</DL>
<H4><A NAME="sec:4.9.3.1"><SPAN class="sec-nr">4.9.3.1</SPAN> <SPAN class="sec-title">Printing
from libraries</SPAN></A></H4>
<A NAME="sec:libprintmsg"></A>
<P>Libraries should <EM>not</EM> use <A NAME="idx:format3:592"></A><A class="pred" href="format.html#format/3">format/3</A>
or other output predicates directly. Libraries that print informational
output directory to the console are hard to use from code that depend on
your textual output, such as a GI script. The predicates in <A class="sec" href="exception.html">section
4.9.3</A> define the API for dealing with messages. The idea behind this
is that a library that wants to provide information about its status,
progress, events or problems calls <A NAME="idx:printmessage2:593"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>.
The first argument is the
<EM>level</EM>. The supported levels are described with <A NAME="idx:printmessage2:594"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>.
Libraries typically use <CODE>informational</CODE> and <CODE>warning</CODE>,
while libraries should use exceptions for errors (see <A NAME="idx:throw1:595"></A><A class="pred" href="exception.html#throw/1">throw/1</A>, <A NAME="idx:typeerror2:596"></A><SPAN class="pred-ext">type_error/2</SPAN>,
etc.).
<P>The second argument is an arbitrary Prolog term that carries te
information of the message, but <EM>not</EM> the precise text. The text
is defined by the grammar rule prolog:message//1. This distinction is
made to allow for translations and to allow hooks processing the
information in a different way (e.g., translate progress messages into a
progress-bar).
<P>For example, suppose we have a library that must download data from
the internet (e.g., based on <A NAME="idx:httpopen3:597"></A><SPAN class="pred-ext">http_open/3</SPAN>).
The library wants to print the progress after each downloaded file. The
code below is a good skeleton:
<PRE class="code">
download_urls(List) :-
length(List, Total),
forall(nth1(I, List, URL),
( download_url(URL),
print_message(informational,
download_url(URL, I, Total)))).
</PRE>
<P>The programmer can now specify the default textual output using the
rule below. Note that this rule may be in the same file or anywhere
else. Notably, the application may come with several rule-sets for
different languages. This, and the user-hook example below are the
reason to represent the message as a compound term rather than a string.
This is similar to using message-numbers in non-symbolic languages. The
documentation of <A NAME="idx:printmessagelines3:598"></A><A class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</A>
describes the elements that may appear in the output list.
<PRE class="code">
:- multifile
prolog:message//1.
prolog:message(download_url(URL, I, Total)) -->
{ Perc is round(I*100/Total) },
[ 'Downloaded ~w; ~D from ~D (~d%)'-[URL, I, Total, Perc] ].
</PRE>
<P>A <EM>user</EM> of the library may define rules for <A NAME="idx:messagehook3:599"></A><A class="pred" href="exception.html#message_hook/3">message_hook/3</A>.
The rule below acts on the message-content. Other applications can act
on the message-level and, for example, popup a message-box for warnings
and errors.
<PRE class="code">
:- multifile user:message_hook/3.
message_hook(download_url(URL, I, Total), _Kind, _Lines) :-
<send this information to a GUI component>
</PRE>
<P>In addition, using the commandline option <STRONG>-q</STRONG>, the
user can disable all <EM>informational</EM> messages.
<P></BODY></HTML>
|