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
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Exception.h File Reference</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
<style type="text/css" media="screen">
body {background-color:white;}
body,div,p,dl,.memname, .params, .exception {font: normal normal normal 16px/22px "HelveticaNeue", Helvetica, "Arial Narrow", Arial, sans-serif;}
#nav-path {display:none;}
h2:first-of-type {margin-top:2px; border:none;}
h2.groupheader {font-size:26px; line-height:28px;color:#286796;}
div.groupheader { font-weight:600; font-size:18px;color: rgb(51, 51, 51);}
h3 {font-size:20px;color: rgb(51, 51, 51);}
div.header { background-image:none; background-color: #3b96d7; color:white;}
div.title {text-align:center;font-size: 28px; font-weight:100;}
.summary {display:none;}
dl.section {border:none;}
.memproto > *, .memitem > * {
box-shadow: none!important;
-moz-box-shadow: none!important;
-webkit-box-shadow: none!important;
background-image:none!important;
}
.memproto {
border-bottom: 1px #b8c8e9 solid;
background-color: #f7fcff;
}
pre {white-space: pre-wrap;}
.textinfo {color: #428bca;}
.textnote {color: #a94442;}
</style>
</head><body>
<!-- Generated by Doxygen 1.8.5 -->
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_bb61871b4c63e4e6685a8d6c52430594.html">zdb</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#define-members">Macros</a> </div>
<div class="headertitle">
<div class="title">Exception.h File Reference</div> </div>
</div><!--header-->
<div class="contents">
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>An <b>Exception</b> indicate an error condition from which recovery may be possible. </p>
<p>The Library <em>raise</em> exceptions, which can be handled by recovery code, if recovery is possible. When an exception is raised, it is handled by the handler that was most recently instantiated. If no handlers are defined an exception will cause the library to call its abort handler to abort with an error message.</p>
<p>Handlers are instantiated by the TRY-CATCH and TRY-FINALLY statements, which are implemented as macros in this interface. These statements handle nested exceptions and manage exception-state data. The syntax of the TRY-CATCH statement is,</p>
<pre>
TRY
<b>S</b>
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(e1)</a>
S1
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(e2)</a>
S2
[...]
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(en)</a>
Sn
END_TRY;
</pre><p>The TRY-CATCH statement establish handlers for the exceptions named <code>e1, e2,.., en</code> and execute the statements <b>S</b>. If no exceptions are raised by <b>S</b>, the handlers are dismantled and execution continues at the statement after the END_TRY. If <b>S</b> raises an exception <code>e</code> which is one of <em>e1..en</em> the execution of <b>S</b> is interrupted and control transfers immediately to the statements following the relevant CATCH clause. If <b>S</b> raises an exception that is <em>not</em> one of <em>e1..en</em>, the exception will raise up the call-stack and unless a previous installed handler catch the exception, it will cause the application to abort.</p>
<p>Here's a concrete example calling a method in the libzdb API which may throw an exception. If the method <a class="el" href="Connection_8h.html#ad7029336959701d33bb921b89bc5b7ef" title="Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL state...">Connection_execute()</a> fails it will throw an SQLException. The CATCH statement will catch this exception, if thrown, and log an error message </p>
<pre>
TRY
[...]
Connection_execute(c, sql);
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(SQLException)</a>
log("SQL error: %s\n", Connection_getLastError(c));
END_TRY;
</pre><p>The TRY-FINALLY statement is similar to TRY-CATCH but in addition adds a FINALLY clausal which is always executed, regardless if an exception was raised or not. The syntax of the TRY-FINALLY statement is, </p>
<pre>
TRY
<b>S</b>
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(e1)</a>
S1
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(e2)</a>
S2
[...]
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(en)</a>
Sn
FINALLY
Sf
END_TRY;
</pre> <p>Note that <code>Sf</code> is executed whether <b>S</b> raise an exception or not. One purpose of the TRY-FINALLY statement is to give clients an opportunity to "clean up" when an exception occurs. For example, </p>
<pre>
TRY
{
[...]
Connection_execute(c, sql);
}
FINALLY
{
Connection_close(c);
}
END_TRY;
</pre><p> closes the database Connection regardless if an exception was thrown or not by the code in the TRY-block. The above example also demonstrate that FINALLY can be used without an exception handler, if an exception was thrown it will be rethrown after the control reaches the end of the finally block. Meaning that we can cleanup even if an exception was thrown and the exception will automatically propagate up the call stack afterwards.</p>
<p>Finally, the RETURN statement, defined in this interface, must be used instead of C return statements inside a try-block. If any of the statements in a try block must do a return, they <b>must</b> do so with this macro instead of the usual C return statement.</p>
<h3>Exception details</h3>
<p>Inside an exception handler, details about an exception is available in the variable <code>Exception_frame</code>. The following demonstrate usage of this variable to provide detailed logging of an exception. For SQL errors, <a class="el" href="Connection_8h.html#af5287b68722604015d3e7f82b0b139ee" title="This method can be used to obtain a string describing the last error that occurred. ">Connection_getLastError()</a> can also be used, though <code>Exception_frame</code> is recommended since in addition to SQL errors, it also cover API errors not directly related to SQL.</p>
<pre>
TRY
{
code that can throw an exception
}
ELSE
{
fprintf(stderr, "%s: %s raised in %s at %s:%d\n",
Exception_frame.exception->name,
Exception_frame.message,
Exception_frame.func,
Exception_frame.file,
Exception_frame.line);
....
}
END_TRY;
</pre><h3>Volatile and assignment inside a try-block</h3>
<p>A variable declared outside a try-block and assigned a value inside said block should be declared <code>volatile</code> if the variable will be accessed from an exception handler. Otherwise the compiler will/may optimize away the value set in the try-block and the handler will not see the new value. Declaring the variable volatile is only necessary if the variable is to be used inside a CATCH or ELSE block. Example: </p>
<pre>
volatile int i = 0;
TRY
{
i = 1;
<throw SQLException>
}
<a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2" title="Defines a block containing code for handling an exception thrown in the TRY block. ">CATCH(SQLException)</a>
{
assert(i == 1); // Unless declared volatile i would be 0 here (implementation dependent)
}
END_TRY;
assert(i == 1); // i will be 1 here regardless if it is declared volatile or not
</pre><h3>Thread-safe</h3>
<p>The Exception stack is stored in a thread-specific variable so Exceptions are made thread-safe. <em>This means that Exceptions are thread local and an Exception thrown in one thread cannot be catched in another thread</em>. This also means that clients must handle Exceptions per thread and cannot use one TRY-ELSE block in the main program to catch all Exceptions. This is only possible if no threads were started. </p>
<p>This implementation is a minor modification of the Except code found in <a href="http://www.drhanson.net/">David R. Hanson's</a> excellent book <a href="http://www.cs.princeton.edu/software/cii/">C Interfaces and Implementations</a>. </p>
<dl class="section see"><dt>See Also</dt><dd><a class="el" href="SQLException_8h.html" title="Signals that an SQL specific exception has occurred. ">SQLException.h</a> </dd></dl>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
Macros</h2></td></tr>
<tr class="memitem:a0acb682b8260ab1c60b918599864e2e5"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#a0acb682b8260ab1c60b918599864e2e5">T</a>   Exception_T</td></tr>
<tr class="separator:a0acb682b8260ab1c60b918599864e2e5"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a4ae81f98d4ed991a128cc95df88c8e4d"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#a4ae81f98d4ed991a128cc95df88c8e4d">THROW</a>(e, cause,...)</td></tr>
<tr class="memdesc:a4ae81f98d4ed991a128cc95df88c8e4d"><td class="mdescLeft"> </td><td class="mdescRight">Throws an exception. <a href="#a4ae81f98d4ed991a128cc95df88c8e4d">More...</a><br/></td></tr>
<tr class="separator:a4ae81f98d4ed991a128cc95df88c8e4d"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a241d764fad0bff69d31c12b3066c276c"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#a241d764fad0bff69d31c12b3066c276c">RETHROW</a></td></tr>
<tr class="memdesc:a241d764fad0bff69d31c12b3066c276c"><td class="mdescLeft"> </td><td class="mdescRight">Re-throws an exception. <a href="#a241d764fad0bff69d31c12b3066c276c">More...</a><br/></td></tr>
<tr class="separator:a241d764fad0bff69d31c12b3066c276c"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a6a0e6b80dd3d5ca395cf58151749f5e2"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#a6a0e6b80dd3d5ca395cf58151749f5e2">RETURN</a></td></tr>
<tr class="memdesc:a6a0e6b80dd3d5ca395cf58151749f5e2"><td class="mdescLeft"> </td><td class="mdescRight">Clients <b>must</b> use this macro instead of C return statements inside a try-block. <a href="#a6a0e6b80dd3d5ca395cf58151749f5e2">More...</a><br/></td></tr>
<tr class="separator:a6a0e6b80dd3d5ca395cf58151749f5e2"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ad2746371528bdf15c3910b7bf217dac0"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#ad2746371528bdf15c3910b7bf217dac0">TRY</a></td></tr>
<tr class="memdesc:ad2746371528bdf15c3910b7bf217dac0"><td class="mdescLeft"> </td><td class="mdescRight">Defines a block of code that can potentially throw an exception. <a href="#ad2746371528bdf15c3910b7bf217dac0">More...</a><br/></td></tr>
<tr class="separator:ad2746371528bdf15c3910b7bf217dac0"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ab3271e393133e395129cc74272f9fae2"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#ab3271e393133e395129cc74272f9fae2">CATCH</a>(e)</td></tr>
<tr class="memdesc:ab3271e393133e395129cc74272f9fae2"><td class="mdescLeft"> </td><td class="mdescRight">Defines a block containing code for handling an exception thrown in the TRY block. <a href="#ab3271e393133e395129cc74272f9fae2">More...</a><br/></td></tr>
<tr class="separator:ab3271e393133e395129cc74272f9fae2"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a0a70ee0cbf5b1738be4c9463c529ce72"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#a0a70ee0cbf5b1738be4c9463c529ce72">ELSE</a></td></tr>
<tr class="memdesc:a0a70ee0cbf5b1738be4c9463c529ce72"><td class="mdescLeft"> </td><td class="mdescRight">Defines a block containing code for handling any exception thrown in the TRY block. <a href="#a0a70ee0cbf5b1738be4c9463c529ce72">More...</a><br/></td></tr>
<tr class="separator:a0a70ee0cbf5b1738be4c9463c529ce72"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a0e2a75478cd44f1666a6aca626c5c50b"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#a0e2a75478cd44f1666a6aca626c5c50b">FINALLY</a></td></tr>
<tr class="memdesc:a0e2a75478cd44f1666a6aca626c5c50b"><td class="mdescLeft"> </td><td class="mdescRight">Defines a block of code that is subsequently executed whether an exception is thrown or not. <a href="#a0e2a75478cd44f1666a6aca626c5c50b">More...</a><br/></td></tr>
<tr class="separator:a0e2a75478cd44f1666a6aca626c5c50b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ae6628ac788ad213363b89dba9868420b"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="Exception_8h.html#ae6628ac788ad213363b89dba9868420b">END_TRY</a></td></tr>
<tr class="memdesc:ae6628ac788ad213363b89dba9868420b"><td class="mdescLeft"> </td><td class="mdescRight">Ends a TRY-CATCH block. <a href="#ae6628ac788ad213363b89dba9868420b">More...</a><br/></td></tr>
<tr class="separator:ae6628ac788ad213363b89dba9868420b"><td class="memSeparator" colspan="2"> </td></tr>
</table>
<h2 class="groupheader">Macro Definition Documentation</h2>
<a class="anchor" id="a0acb682b8260ab1c60b918599864e2e5"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define <a class="el" href="Connection_8h.html#a8dc1b239f8e305fbd1406ff041c89151">T</a>   Exception_T</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a class="anchor" id="a4ae81f98d4ed991a128cc95df88c8e4d"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define THROW</td>
<td>(</td>
<td class="paramtype"> </td>
<td class="paramname">e, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"> </td>
<td class="paramname">cause, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"> </td>
<td class="paramname"><em>...</em> </td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Throws an exception. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">e</td><td>The Exception to throw </td></tr>
<tr><td class="paramname">cause</td><td>The cause. A NULL value is permitted, and indicates that the cause is unknown. </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a class="anchor" id="a241d764fad0bff69d31c12b3066c276c"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define RETHROW</td>
</tr>
</table>
</div><div class="memdoc">
<p>Re-throws an exception. </p>
<p>In a CATCH or ELSE block clients can use RETHROW to re-throw the Exception </p>
</div>
</div>
<a class="anchor" id="a6a0e6b80dd3d5ca395cf58151749f5e2"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define RETURN</td>
</tr>
</table>
</div><div class="memdoc">
<p>Clients <b>must</b> use this macro instead of C return statements inside a try-block. </p>
</div>
</div>
<a class="anchor" id="ad2746371528bdf15c3910b7bf217dac0"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define TRY</td>
</tr>
</table>
</div><div class="memdoc">
<p>Defines a block of code that can potentially throw an exception. </p>
</div>
</div>
<a class="anchor" id="ab3271e393133e395129cc74272f9fae2"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define CATCH</td>
<td>(</td>
<td class="paramtype"> </td>
<td class="paramname">e</td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Defines a block containing code for handling an exception thrown in the TRY block. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">e</td><td>The Exception to handle </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a class="anchor" id="a0a70ee0cbf5b1738be4c9463c529ce72"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define ELSE</td>
</tr>
</table>
</div><div class="memdoc">
<p>Defines a block containing code for handling any exception thrown in the TRY block. </p>
<p>An ELSE block catches any exception type not already catched in a previous CATCH block. </p>
</div>
</div>
<a class="anchor" id="a0e2a75478cd44f1666a6aca626c5c50b"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define FINALLY</td>
</tr>
</table>
</div><div class="memdoc">
<p>Defines a block of code that is subsequently executed whether an exception is thrown or not. </p>
</div>
</div>
<a class="anchor" id="ae6628ac788ad213363b89dba9868420b"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define END_TRY</td>
</tr>
</table>
</div><div class="memdoc">
<p>Ends a TRY-CATCH block. </p>
</div>
</div>
</div><!-- contents -->
<p style="text-align:center;color:#808080;font-size:90%;margin:40px 0 20px 0;">
Copyright © <a href="http://tildeslash.com/">Tildeslash Ltd</a>. All
rights reserved.</p>
</body></html>
|