PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/docs/sg/Error recovery.html

https://bitbucket.org/kib2/wikiparser
HTML | 280 lines | 277 code | 3 blank | 0 comment | 0 complexity | 17f62342bd240b2e9717a28648300e91 MD5 | raw file
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  3. <head>
  4. <meta name="Description" content="Information architecture, Web Design, Web Standards." />
  5. <meta name="Keywords" content="falcon, programming" />
  6. <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
  7. <link rel="stylesheet" href="Ablaze.css" type="text/css" media="screen" />
  8. <title>Error recovery</title>
  9. </head>
  10. <body>
  11. <!-- header starts here -->
  12. <div id="header"><div id="header-content">
  13. <h1 id="logo">Falcon's Survival Guide</h1>
  14. <h2 id="slogan">lets you get started with Falcon</h2>
  15. </div></div>
  16. <!-- content-wrap starts here -->
  17. <div id="content-wrap"><div id="content">
  18. <div id="sidebar" >
  19. <div class="sidebox">
  20. <h1>Navigation:</h1>
  21. <ol>
  22. <li><a href="Falcon's%20Survival%20Guide.html">Falcon's Survival Guide</a></li>
  23. <li><a href="Introduction.html">Introduction</a></li>
  24. <li><a href="Control%20structures.html">Control structures</a></li>
  25. <li><a href="Basic%20Datatypes.html">Basic Datatypes</a></li>
  26. <li><a href="The%20functions.html">The functions</a></li>
  27. <li><a href="Functional%20programming.html">Functional programming</a></li>
  28. <li><a href="Objects%20and%20classes.html">Objects and classes</a></li>
  29. <li><a href="Prototype%20based%20OOP.html">Prototype based OOP</a></li>
  30. <li><a href="Tabular%20programming.html">Tabular programming</a></li>
  31. <li><a href="Iterators.html">Iterators</a></li>
  32. <li><a href="Error%20recovery.html">Error recovery</a></li>
  33. <li><a href="Falcon%20modules.html">Falcon modules</a></li>
  34. <li><a href="The%20directive%20statement.html">The directive statement</a></li>
  35. <li><a href="Advanced%20topics.html">Advanced topics</a></li>
  36. </ol>
  37. </div>
  38. <div class="sidebox">
  39. <h1>Table of contents:</h1>
  40. <ul>
  41. <li><a href="#Error-recovery">Error recovery</a>
  42. <ul>
  43. <li><a href="#Raising-errors">Raising errors</a></li>
  44. </ul>
  45. </li>
  46. </ul>
  47. </div>
  48. <div class="sidebox">
  49. <h1>Wise Words</h1>
  50. <p>&quot;Falcon provides six integrated programming paradigms: procedural, object oriented, prototype oriented, functional, tabular and message oriented. And you don't have to master all of them; you just need to pick the ingredients you prefer, and let the code to follow your inspiration&quot;</p>
  51. </div>
  52. </div>
  53. <div id="main">
  54. <!-- Generated by Falcon Markup Engine -->
  55. <center class="navi">Previous: <a class="navi" href="Iterators.html">Iterators</a> -- Top: <a class="navi" href="Falcon's Survival Guide.html">Falcon's Survival Guide</a> -- Next: <a class="navi" href="Falcon modules.html">Falcon modules</a>
  56. </center>
  57. <h1><a name="Error-recovery">Error recovery</a></h1>
  58. <p>You'll remember our first interactive Falcon script: that was the one asking you for your age and then entering a loop congratulating with you many times for your past birthdays. </p>
  59. <p>The int() function tried to convert a string (what you typed) into an integer (your age), but if this was not possible for some reason, a runtime error appeared instead, and the program was terminated. Here follows a reduced version of that script that will serve our needs:</p>
  60. <pre>
  61. <span class="falKeywords2">print</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Enter your age: &gt; </span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  62. age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  63. count <span class="falOperators">=</span> <span class="Integer">0</span>
  64. <span class="falKeywords">while</span> count <span class="falOperators">&lt;</span> age
  65. count <span class="falOperators">+</span><span class="falOperators">=</span> <span class="Integer">1</span>
  66. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Happy belated birthday for your </span><span class="falDoubleString">"</span><span class="falPars">,</span> count<span class="falPars">,</span> <span class="falDoubleString">"</span><span class="falDoubleString">.</span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  67. <span class="falKeywords">end</span> </pre>
  68. <p>Falcon provides a mechanism to handle unexpected situations that may arise in a program. Many library functions and language constructs use this mechanism to communicate with the controlling script about unexpected situations, but this system is also available to the script itself, so that script writers can take advantage of this. It's called exception raising .</p>
  69. <p>Every time the Virtual Machine, one of the library functions or even other script parts run into a potentially dangerous situation, they raise an exception. If this exception is not handled somehow by the script, it is handed back to the system; the Falcon interpreter will print an error message and exit.</p>
  70. <p><blockquote>If the Falcon Virtual Machine is used by an embedding application to run some scripts, the embedder has the ability to set a top level exception handler. This will usually grant the embedding application the ability to know about fatal errors in the scripts, and take sensible actions (as i.e. mailing the administrators). </blockquote></p>
  71. <p>There are a set of exceptions that are called unstoppable . These exceptions are raised by library functions or by the Virtual Machine itself if it finds some critical condition that may prevent scripts from working, as for example script bytecode corruptions. In those situations, letting the scripts intercept the exceptions would not be wise, hence the need of unstoppable exceptions.</p>
  72. <p>Exceptions can be handled by the script by using the try - catch control block:</p>
  73. <pre>
  74. <span class="falKeywords">try</span>
  75. <span class="falPars">[</span><span class="falKeywords">try</span> statements<span class="falPars">]</span>
  76. <span class="falPars">[</span> <span class="falKeywords">catch</span> <span class="falPars">[</span>object_type<span class="falPars">]</span> <span class="falPars">[</span> <span class="falLogic">in</span> error_variable<span class="falPars">]</span> <span class="falPars">]</span>
  77. <span class="falPars">[</span> <span class="falKeywords">catch</span> statements <span class="falPars">]</span>
  78. <span class="falKeywords">end</span> </pre>
  79. <p>Each catch block can intercept a certain kind of variable. The working principle is the same as the <tt>select</tt> statement; a type can be one of the type names, or it can be the name of a symbol declared somewhere in the program.</p>
  80. <p>Try-catch blocks can be nested (put one into another) or combined with any other Falcon block statement ( <tt>if</tt>, <tt>while</tt>, <tt>for</tt>, <tt>function</tt> and so on). The try-catch block functionality is as follows: whenever an instruction inside the try (try-statements) causes an exception to be raised, the control flow is immediately broken. If a catch block is present, the type of the raised object is matched against the type specifiers of the catch blocks. Overall types (as i.e. StringType or ObjectType) get precedence, then the specific symbols used as specifiers are considered in the order they are declared in the catch clauses. For this reason, catch blocks intercepting subclasses should be declared before the ones intercepting parent classes. Finally, if none of the typed catch blocks matches the raised exception, the raised error is passed to a catch hander without type declaration, if present. If a typeless catch clause is not present, the error is then raised to the application level and this usually terminates the script.</p>
  81. <p>The following example ensures that the user will write a numeric entry: </p>
  82. <pre>
  83. age <span class="falOperators">=</span> <span class="Integer">0</span>
  84. <span class="falKeywords">while</span> age <span class="falOperators">=</span><span class="falOperators">=</span> <span class="Integer">0</span>
  85. <span class="falKeywords2">print</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Enter your age: &gt; </span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  86. <span class="falKeywords">try</span>
  87. age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  88. <span class="falKeywords">catch</span>
  89. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Please, enter a numeric value</span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  90. <span class="falKeywords">end</span>
  91. <span class="falKeywords">end</span> </pre>
  92. <p>A catch clause may have an optional variable that will be filled with the exception that has been raised in the try block. The exception can be any Falcon item (including numbers, strings and objects) that describes what exactly was the error condition. By convention, the Virtual Machine and all the library functions will only raise an object of class <tt>Error</tt> , or one of its subclasses. However, scripts and other extensions libraries may raise any kind of item.</p>
  93. <p>The Error class provides a series of accessors, that is, methods that are specifically used to access data in the inner object. Normally, scripts are not very interested in peeking the data inside an Error instance; usually, the embedding application is the entity that is meant to intercept errors and deal with them. For this reason, the embedding API puts at library disposal a C++ class called Falcon::Error; in case the script wants to intercept it, and only in that case, the C++ object is wrapped in Falcon object, and methods are used to query the internal Falcon::Error C++ instance. This is because intercepting and analyzing Error instances from scripts is considered an extraordinary operation; the overhead introduced by using methods instead of plain properties to retrieve Error values is marginal with respect to the advantage the embedding application receives by being able to use directly C++ objects in its code when a forbidding error condition is encountered by the script. </p>
  94. <p>The content of an Error Objects is enumerated in the Function Reference manual. Please, refer to that guide for the details. </p>
  95. <p>Now we can print a more descriptive error message about what the user should do in our test program: </p>
  96. <pre>
  97. age <span class="falOperators">=</span> <span class="Integer">0</span>
  98. <span class="falKeywords">while</span> age <span class="falOperators">=</span><span class="falOperators">=</span> <span class="Integer">0</span>
  99. <span class="falKeywords2">print</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Enter your age: &gt; </span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  100. <span class="falKeywords">try</span>
  101. age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  102. <span class="falKeywords">catch</span> <span class="falLogic">in</span> error <span class="falComment">// any variable name is ok here</span>
  103. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Oops, you caused the error number </span><span class="falDoubleString">"</span><span class="falPars">,</span> error<span class="Integer">.</span>getCode<span class="falPars">(</span><span class="falPars">)</span><span class="falPars">,</span>
  104. <span class="falDoubleString">"</span><span class="falDoubleString">\nwhich means that: </span><span class="falDoubleString">"</span><span class="falPars">,</span> error<span class="Integer">.</span>getMessage<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  105. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Please, enter a numeric value</span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  106. <span class="falKeywords">end</span>
  107. <span class="falKeywords">end</span> </pre>
  108. <p>Do not confuse the <tt>Error</tt> class with the above <tt>error</tt> variable: Falcon is fully case-sensitive, so the variable we named <tt>error</tt> in the above code is just a normal variable receiving an <tt>Error</tt> class instance.</p>
  109. <p>Notice that the catch block is not immune to error raising. If an exception is raised inside a catch block, it will have exactly the same effect as if it were raised in any other part of the program: it may be caught again with another try/catch block, or it may be left to handle to the above handlers, or finally to the Virtual Machine. We'll see in a moment how this fact can be useful.</p>
  110. <p>The <tt>try</tt> instruction can be abbreviated with the : operator; it wont be possible to catch any error in this case, but this may be useful in case any possible error must simply be discarded:</p>
  111. <pre>
  112. <span class="falKeywords">try</span>
  113. age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  114. <span class="falKeywords">end</span>
  115. <span class="falComment">// is equivalent to</span>
  116. <span class="falKeywords">try</span><span class="falOperators">:</span> age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span></pre>
  117. <h2><a name="Raising-errors">Raising errors</a></h2>
  118. <p>It is interesting to be able to raise errors; the execution flow is immediately interrupted and a possible error manager is invoked, so raising errors inside the scripts may often obviate the need for "if" sequences, each of them checking for the right things to be done at each step. The keyword <tt>raise</tt> makes an item to be thrown and treats it as an exception.</p>
  119. <p>The script may choose two different approaches to raise errors: one is that of creating an instance of the Error class using the Error() constructor, which accepts the following parameters:</p>
  120. <pre>
  121. Error<span class="falPars">(</span> code<span class="falPars">,</span> message<span class="falPars">,</span> comment <span class="falPars">)</span></pre>
  122. <p>However, sometimes it is useful to throw a lighter object. Suppose that we want to set a maximum and minimum age in our example, and that we cause an error to be raised when those limits are not respected. In this case, that we may call flow control exception raising , having a full error to be raised may be an overkill. Follow this example:</p>
  123. <pre>
  124. age <span class="falOperators">=</span> <span class="Integer">0</span>
  125. <span class="falKeywords">loop</span>
  126. <span class="falKeywords2">print</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Enter your age: &gt; </span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  127. <span class="falKeywords">try</span>
  128. age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  129. <span class="falKeywords">if</span> age <span class="falOperators">&lt;</span> <span class="Integer">3</span><span class="falOperators">:</span> <span class="falKeywords2">raise</span> <span class="falDoubleString">"</span><span class="falDoubleString">Sorry, you are too young to type.</span><span class="falDoubleString">"</span>
  130. <span class="falKeywords">if</span> age <span class="falOperators">&gt;</span> <span class="Integer">150</span><span class="falOperators">:</span> <span class="falKeywords2">raise</span> <span class="falDoubleString">"</span><span class="falDoubleString">Sorry, age limit for humans is 150.</span><span class="falDoubleString">"</span>
  131. <span class="falKeywords">catch</span> <span class="falTypes">StringType</span> <span class="falLogic">in</span> error
  132. <span class="falKeywords2">printl</span><span class="falPars">(</span> error <span class="falPars">)</span>
  133. <span class="falComment">// age has been correctly assigned. Change it:</span>
  134. age <span class="falOperators">=</span> <span class="Integer">0</span>
  135. <span class="falKeywords">catch</span> Error <span class="falLogic">in</span> error
  136. <span class="falComment">// it's a standard error of Error class, manage it normally</span>
  137. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Oops, you caused the error number </span><span class="falDoubleString">"</span><span class="falPars">,</span> error<span class="Integer">.</span>code<span class="falPars">,</span>
  138. <span class="falDoubleString">"</span><span class="falDoubleString">\nwhich means that: </span><span class="falDoubleString">"</span><span class="falPars">,</span> error<span class="Integer">.</span>description <span class="falPars">)</span>
  139. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Please, enter a numeric value</span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  140. <span class="falKeywords">catch</span> <span class="falLogic">in</span> error
  141. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">Something else was raised... but I don't know what...</span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  142. <span class="falKeywords2">printl</span><span class="falPars">(</span> <span class="falDoubleString">"</span><span class="falDoubleString">So I raise it again and the app will die.</span><span class="falDoubleString">"</span> <span class="falPars">)</span>
  143. <span class="falKeywords2">raise</span> error
  144. <span class="falKeywords">end</span>
  145. <span class="falKeywords">end</span> age <span class="falOperators">!</span><span class="falOperators">=</span> <span class="Integer">0</span></pre>
  146. <p>In this way, we have a controlled interruption of the normal code flow which is passed to the StringType catch branch, with a minimal overhead with respect to the equivalent code performed with a series of branches. If the weight of those branches becomes relevant, the exception code flow control may be even more efficient (the virtual machine management of try-catch blocks is comparatively light with respect to any other kind of operation), while it may be more elegant, and possibly more readable. </p>
  147. <p>It is also to be noticed that the caught variable may be parsed through a select statement. This may or may be an interesting opportunity, depending on the needed flexibility. The above code is equivalent to the following: </p>
  148. <pre>
  149. <span class="falComment">// the rest as before...</span>
  150. <span class="falKeywords">try</span>
  151. age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
  152. <span class="falKeywords">if</span> age <span class="falOperators">&lt;</span> <span class="Integer">3</span><span class="falOperators">:</span> <span class="falKeywords2">raise</span> <span class="falDoubleString">"</span><span class="falDoubleString">Sorry you are too young to type.</span><span class="falDoubleString">"</span>
  153. <span class="falKeywords">if</span> age <span class="falOperators">&gt;</span> <span class="Integer">150</span><span class="falOperators">:</span> <span class="falKeywords2">raise</span> <span class="falDoubleString">"</span><span class="falDoubleString">Sorry, age limit for humans is 150.</span><span class="falDoubleString">"</span>
  154. <span class="falKeywords">catch</span> <span class="falLogic">in</span> error
  155. <span class="falKeywords">select</span> error
  156. <span class="falKeywords">case</span> <span class="falTypes">StringType</span>
  157. <span class="falComment">// manage strings as before</span>
  158. <span class="falKeywords">case</span> Error
  159. <span class="falComment">// manage Error instances as before...</span>
  160. <span class="falKeywords">default</span>
  161. <span class="falComment">// print something as before... </span>
  162. <span class="falKeywords2">raise</span> error
  163. <span class="falKeywords">end</span>
  164. <span class="falKeywords">end</span> </pre>
  165. <p>This solution is a visually a bit less compact, requiring three indent levels where the previous only needed one. Also, the VM has an opcode that manages a typed catch a bit faster than a select statement (it's one VM opcode less, actually, but the opcode that is skipped with the typed catch approach is quite fast to be executed). However, it presents two advantages: first of all, it is possible to execute some common code before or/and after any specific error management. Secondly, the select code may be delegated to a function (or to a lambda) that may be changed on the fly during program execution, actually changing the error management policy for that section. Through this kind of semantics, a common error management policy may be given to different handlers. As this doesn't prevent writing specific typed catches, each error management code may be highly customized through a combination of static typed catch statements and dynamic catch-everything statements passing the raised value to a common manager.</p>
  166. <center class="navi">Previous: <a class="navi" href="Iterators.html">Iterators</a> -- Top: <a class="navi" href="Falcon's Survival Guide.html">Falcon's Survival Guide</a> -- Next: <a class="navi" href="Falcon modules.html">Falcon modules</a>
  167. </center>
  168. <!-- END of document generated by Falcon Markup Engine -->
  169. </div>
  170. <!-- content-wrap ends here -->
  171. </div></div>
  172. <!-- footer starts here -->
  173. <div id="footer"><div id="footer-content">
  174. <div class="col float-left">
  175. <h2>Site Partners</h2>
  176. <ul>
  177. <li><a href="http://falconpl.org"><strong>Falcon</strong> - The programming langage</a></li>
  178. <li><a href="http://falconpl.org/index.ftd?page_id=manuals"><strong>Falcon manuals</strong> - If you want to go further</a></li>
  179. </ul>
  180. </div>
  181. <div class="col float-left">
  182. <h2>Links</h2>
  183. <ul>
  184. <li><a href="http://www.openwebdesign.org/"><strong>openwebdesign.org</strong></a></li>
  185. <li><a href="http://www.OSWD.org/"><strong>OSWD.org</strong></a></li>
  186. <li><a href="http://www.zeroweb.org/"><strong>zeroweb.org</strong></a></li>
  187. <li><a href="http://www.alistapart.com/"><strong>Alistapart</strong></a></li>
  188. <li><a href="http://www.cssremix.com/"><strong>CSS Remix</strong></a></li>
  189. </ul>
  190. </div>
  191. <div class="col2 float-right">
  192. <p>
  193. &copy; copyright 2009 <strong>Jonnymind</strong><br />
  194. Design by: <a href="index.html"><strong>styleshout</strong></a> &nbsp; &nbsp;
  195. Valid <a href="http://jigsaw.w3.org/css-validator/check/referer"><strong>CSS</strong></a> |
  196. <a href="http://validator.w3.org/check/referer"><strong>XHTML</strong></a>
  197. <br />
  198. Contents of this guide is generated by Falcon's wikiparser and highlighter modules &copy; KibĀ?.
  199. </p>
  200. </div>
  201. </div></div>
  202. <!-- footer ends here -->
  203. </body>
  204. </html>