PageRenderTime 28ms CodeModel.GetById 2ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/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
  3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4
  5<head>
  6
  7<meta name="Description" content="Information architecture, Web Design, Web Standards." />
  8<meta name="Keywords" content="falcon, programming" />
  9<meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
 10<link rel="stylesheet" href="Ablaze.css" type="text/css" media="screen" />
 11
 12<title>Error recovery</title>
 13	
 14</head>
 15
 16<body>
 17
 18	<!-- header starts here -->
 19	<div id="header"><div id="header-content">	
 20		
 21		<h1 id="logo">Falcon's Survival Guide</h1>	
 22		<h2 id="slogan">lets you get started with Falcon</h2>			
 23	
 24	</div></div>
 25				
 26	<!-- content-wrap starts here -->
 27	<div id="content-wrap"><div id="content">	 
 28	
 29		<div id="sidebar" >				
 30			<div class="sidebox">
 31			<h1>Navigation:</h1>
 32			<ol>
 33<li><a href="Falcon's%20Survival%20Guide.html">Falcon's Survival Guide</a></li>
 34<li><a href="Introduction.html">Introduction</a></li>
 35<li><a href="Control%20structures.html">Control structures</a></li>
 36<li><a href="Basic%20Datatypes.html">Basic Datatypes</a></li>
 37<li><a href="The%20functions.html">The functions</a></li>
 38<li><a href="Functional%20programming.html">Functional programming</a></li>
 39<li><a href="Objects%20and%20classes.html">Objects and classes</a></li>
 40<li><a href="Prototype%20based%20OOP.html">Prototype based OOP</a></li>
 41<li><a href="Tabular%20programming.html">Tabular programming</a></li>
 42<li><a href="Iterators.html">Iterators</a></li>
 43<li><a href="Error%20recovery.html">Error recovery</a></li>
 44<li><a href="Falcon%20modules.html">Falcon modules</a></li>
 45<li><a href="The%20directive%20statement.html">The directive statement</a></li>
 46<li><a href="Advanced%20topics.html">Advanced topics</a></li>
 47</ol>
 48
 49			</div>
 50			
 51			<div class="sidebox">
 52			<h1>Table of contents:</h1>
 53			<ul>
 54<li><a href="#Error-recovery">Error recovery</a>
 55    <ul>
 56    <li><a href="#Raising-errors">Raising errors</a></li>
 57    </ul>
 58</li>
 59</ul>
 60
 61			</div>
 62					
 63			<div class="sidebox">
 64				<h1>Wise Words</h1>
 65			
 66				<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>		
 67		
 68			</div>	
 69	
 70				
 71		</div>	
 72	
 73		<div id="main">		
 74<!-- Generated by Falcon Markup Engine -->
 75<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>
 76</center>
 77<h1><a name="Error-recovery">Error recovery</a></h1>
 78
 79<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>
 80
 81<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>
 82
 83<pre>
 84<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> 
 85age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span> 
 86 
 87count <span class="falOperators">=</span> <span class="Integer">0</span> 
 88<span class="falKeywords">while</span> count <span class="falOperators">&lt;</span> age
 89   count <span class="falOperators">+</span><span class="falOperators">=</span> <span class="Integer">1</span>
 90   <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>
 91<span class="falKeywords">end</span> </pre>
 92
 93<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>
 94
 95<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>
 96
 97<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>
 98
 99<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>
100
101<p>Exceptions can be handled by the script by using the try  -  catch control block:</p>
102
103<pre>
104<span class="falKeywords">try</span> 
105   <span class="falPars">[</span><span class="falKeywords">try</span> statements<span class="falPars">]</span>
106<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>
107   <span class="falPars">[</span> <span class="falKeywords">catch</span> statements <span class="falPars">]</span>
108<span class="falKeywords">end</span> </pre>
109
110<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>
111
112<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>
113
114<p>The following example ensures that the user will write a numeric entry: </p>
115
116<pre>
117age <span class="falOperators">=</span> <span class="Integer">0</span> 
118<span class="falKeywords">while</span> age <span class="falOperators">=</span><span class="falOperators">=</span> <span class="Integer">0</span>
119   <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>
120 
121   <span class="falKeywords">try</span> 
122      age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
123   <span class="falKeywords">catch</span> 
124      <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>
125   <span class="falKeywords">end</span> 
126<span class="falKeywords">end</span> </pre>
127
128<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>
129
130<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>
131
132<p>The content of an Error Objects is enumerated in the Function Reference manual. Please, refer to that guide for the details. </p>
133
134<p>Now we can print a more descriptive error message about what the user should do in our test program: </p>
135
136<pre>
137age <span class="falOperators">=</span> <span class="Integer">0</span> 
138<span class="falKeywords">while</span> age <span class="falOperators">=</span><span class="falOperators">=</span> <span class="Integer">0</span>
139   <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>
140 
141   <span class="falKeywords">try</span> 
142      age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
143   <span class="falKeywords">catch</span> <span class="falLogic">in</span> error   <span class="falComment">// any variable name is ok here</span>
144      <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>
145            <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>
146      <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>
147   <span class="falKeywords">end</span> 
148<span class="falKeywords">end</span> </pre>
149
150<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>
151
152<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>
153
154<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>
155
156<pre>
157    <span class="falKeywords">try</span> 
158       age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
159    <span class="falKeywords">end</span> 
160   
161   <span class="falComment">// is equivalent to</span>
162 
163    <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>
164
165<h2><a name="Raising-errors">Raising errors</a></h2>
166
167<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>
168
169<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>
170
171<pre>
172Error<span class="falPars">(</span> code<span class="falPars">,</span> message<span class="falPars">,</span> comment <span class="falPars">)</span></pre>
173
174<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>
175
176<pre>
177age <span class="falOperators">=</span> <span class="Integer">0</span> 
178<span class="falKeywords">loop</span>
179   <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>
180 
181   <span class="falKeywords">try</span> 
182      age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
183      <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>
184      <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>
185 
186   <span class="falKeywords">catch</span> <span class="falTypes">StringType</span> <span class="falLogic">in</span> error  
187      <span class="falKeywords2">printl</span><span class="falPars">(</span> error <span class="falPars">)</span>
188      <span class="falComment">// age has been correctly assigned. Change it:</span>
189      age <span class="falOperators">=</span> <span class="Integer">0</span>
190 
191   <span class="falKeywords">catch</span> Error <span class="falLogic">in</span> error
192      <span class="falComment">// it's a standard error of Error class, manage it normally</span>
193      <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>
194            <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>
195      <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>
196 
197   <span class="falKeywords">catch</span> <span class="falLogic">in</span> error
198       <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>
199       <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>
200        <span class="falKeywords2">raise</span> error
201    <span class="falKeywords">end</span> 
202<span class="falKeywords">end</span> age <span class="falOperators">!</span><span class="falOperators">=</span> <span class="Integer">0</span></pre>
203
204<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>
205
206<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>
207
208<pre>
209   <span class="falComment">// the rest as before...</span>
210 
211   <span class="falKeywords">try</span>
212      age <span class="falOperators">=</span> int<span class="falPars">(</span> input<span class="falPars">(</span><span class="falPars">)</span> <span class="falPars">)</span>
213      <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>
214      <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>
215 
216   <span class="falKeywords">catch</span> <span class="falLogic">in</span> error  
217      <span class="falKeywords">select</span> error
218          <span class="falKeywords">case</span> <span class="falTypes">StringType</span>
219            <span class="falComment">// manage strings as before</span>
220 
221          <span class="falKeywords">case</span> Error
222            <span class="falComment">// manage Error instances as before...</span>
223 
224          <span class="falKeywords">default</span> 
225            <span class="falComment">// print something as before... </span>
226            <span class="falKeywords2">raise</span> error
227      <span class="falKeywords">end</span> 
228   <span class="falKeywords">end</span> </pre>
229
230<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>
231
232<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>
233</center>
234<!-- END of document generated by Falcon Markup Engine -->
235		</div>			
236		
237	
238	<!-- content-wrap ends here -->		
239	</div></div>
240
241	<!-- footer starts here -->	
242	<div id="footer"><div id="footer-content">
243	
244		<div class="col float-left">
245			<h2>Site Partners</h2>
246			<ul>				
247				<li><a href="http://falconpl.org"><strong>Falcon</strong> - The programming langage</a></li>
248				<li><a href="http://falconpl.org/index.ftd?page_id=manuals"><strong>Falcon manuals</strong> - If you want to go further</a></li>
249			</ul>			
250		</div>
251		
252		<div class="col float-left">
253			<h2>Links</h2>
254			<ul>				
255				<li><a href="http://www.openwebdesign.org/"><strong>openwebdesign.org</strong></a></li>
256				<li><a href="http://www.OSWD.org/"><strong>OSWD.org</strong></a></li>
257				<li><a href="http://www.zeroweb.org/"><strong>zeroweb.org</strong></a></li>
258				<li><a href="http://www.alistapart.com/"><strong>Alistapart</strong></a></li>		
259				<li><a href="http://www.cssremix.com/"><strong>CSS Remix</strong></a></li>					
260			</ul>			
261		</div>		
262	
263		<div class="col2 float-right">
264			<p>
265			&copy; copyright 2009 <strong>Jonnymind</strong><br /> 
266			Design by: <a href="index.html"><strong>styleshout</strong></a> &nbsp; &nbsp;
267			Valid <a href="http://jigsaw.w3.org/css-validator/check/referer"><strong>CSS</strong></a> | 
268		   	   <a href="http://validator.w3.org/check/referer"><strong>XHTML</strong></a>
269		   <br />
270		   Contents of this guide is generated by Falcon's wikiparser and highlighter modules &copy; Kib´┐Ż?.
271			</p>
272		
273
274		</div>
275	
276	</div></div>
277	<!-- footer ends here -->
278
279</body>
280</html>