/usr/share/doc/swi-prolog-doc/Manual/exception.html is in swi-prolog-doc 5.6.59-2.
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 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>SWI-Prolog 5.6.59 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=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;
}
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;
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="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:522"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
and <A NAME="idx:throw1:523"></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>
<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:524"></A><A class="pred" href="metacall.html#call/1">call/1</A>
if no exception is raised when executing <VAR>Goal</VAR>. If a exception
is raised using <A NAME="idx:throw1:525"></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:526"></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:527"></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:528"></A><A class="pred" href="metacall.html#call/1">call/1</A>.
<P>The overhead of calling a goal through <A NAME="idx:catch3:529"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
is very comparable to
<A NAME="idx:call1:530"></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:531"></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:532"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
call. See <A NAME="idx:catch3:533"></A><A class="pred" href="exception.html#catch/3">catch/3</A>
for details.
<P>ISO demands <A NAME="idx:throw1:534"></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:535"></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:536"></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:537"></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:538"></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">30<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, PL_next_solution() fails
and the exception context can be retrieved using PL_exception().
</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:539"></A><A NAME="idx:debuggingexceptions:540"></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:541"></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:542"></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:543"></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>
<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 PL_exception().
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:544"></A><A class="pred" href="debugger.html#debug/0">debug/0</A>.
The hook
<A NAME="idx:prologexceptionhook4:545"></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:546"></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:547"></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:548"></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>
<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:549"></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:550"></A><A NAME="idx:quiet:551"></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:552"></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:553"></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:554"></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:555"></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:556"></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:557"></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>
<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:558"></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:559"></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:560"></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:561"></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:562"></A><A class="pred" href="exception.html#print_message/2">print_message/2</A>
and <A NAME="idx:messagehook3:563"></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:564"></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:565"></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:566"></A><A class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</A>.
See also
<A NAME="idx:messagetostring2:567"></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.23</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>
<P></BODY></HTML>
|