manual split up into multiple files; documented the new concurrency system
This commit is contained in:
parent
e9dec2feed
commit
2c1f3f75f5
31 changed files with 6198 additions and 5901 deletions
132
doc/manual/exceptions.txt
Normal file
132
doc/manual/exceptions.txt
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
Exception handling
|
||||
==================
|
||||
|
||||
Try statement
|
||||
-------------
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
# read the first two lines of a text file that should contain numbers
|
||||
# and tries to add them
|
||||
var
|
||||
f: File
|
||||
if open(f, "numbers.txt"):
|
||||
try:
|
||||
var a = readLine(f)
|
||||
var b = readLine(f)
|
||||
echo("sum: " & $(parseInt(a) + parseInt(b)))
|
||||
except OverflowError:
|
||||
echo("overflow!")
|
||||
except ValueError:
|
||||
echo("could not convert string to integer")
|
||||
except IOError:
|
||||
echo("IO error!")
|
||||
except:
|
||||
echo("Unknown exception!")
|
||||
finally:
|
||||
close(f)
|
||||
|
||||
|
||||
The statements after the ``try`` are executed in sequential order unless
|
||||
an exception ``e`` is raised. If the exception type of ``e`` matches any
|
||||
listed in an ``except`` clause the corresponding statements are executed.
|
||||
The statements following the ``except`` clauses are called
|
||||
`exception handlers`:idx:.
|
||||
|
||||
The empty `except`:idx: clause is executed if there is an exception that is
|
||||
not listed otherwise. It is similar to an ``else`` clause in ``if`` statements.
|
||||
|
||||
If there is a `finally`:idx: clause, it is always executed after the
|
||||
exception handlers.
|
||||
|
||||
The exception is *consumed* in an exception handler. However, an
|
||||
exception handler may raise another exception. If the exception is not
|
||||
handled, it is propagated through the call stack. This means that often
|
||||
the rest of the procedure - that is not within a ``finally`` clause -
|
||||
is not executed (if an exception occurs).
|
||||
|
||||
|
||||
Except and finally statements
|
||||
-----------------------------
|
||||
|
||||
``except`` and ``finally`` can also be used as a stand-alone statements.
|
||||
Any statements following them in the current block will be considered to be
|
||||
in an implicit try block:
|
||||
|
||||
.. code-block:: nim
|
||||
var f = open("numbers.txt")
|
||||
finally: close(f)
|
||||
...
|
||||
|
||||
The ``except`` statement has a limitation in this form: one can't specify the
|
||||
type of the exception, one has to catch everything. Also, if one wants to use
|
||||
both ``finally`` and ``except`` one needs to reverse the usual sequence of the
|
||||
statements. Example:
|
||||
|
||||
.. code-block:: nim
|
||||
proc test() =
|
||||
raise newException(Exception, "Hey ho")
|
||||
|
||||
proc tester() =
|
||||
finally: echo "3. Finally block"
|
||||
except: echo "2. Except block"
|
||||
echo "1. Pre exception"
|
||||
test()
|
||||
echo "4. Post exception"
|
||||
# --> 1, 2, 3 is printed, 4 is never reached
|
||||
|
||||
|
||||
Raise statement
|
||||
---------------
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
raise newEOS("operating system failed")
|
||||
|
||||
Apart from built-in operations like array indexing, memory allocation, etc.
|
||||
the ``raise`` statement is the only way to raise an exception.
|
||||
|
||||
.. XXX document this better!
|
||||
|
||||
If no exception name is given, the current exception is `re-raised`:idx:. The
|
||||
`ReraiseError`:idx: exception is raised if there is no exception to
|
||||
re-raise. It follows that the ``raise`` statement *always* raises an
|
||||
exception (unless a raise hook has been provided).
|
||||
|
||||
|
||||
onRaise builtin
|
||||
---------------
|
||||
|
||||
`system.onRaise() <system.html#onRaise>`_ can be used to override the
|
||||
behaviour of ``raise`` for a single ``try`` statement. ``onRaise`` has to be
|
||||
called within the ``try`` statement that should be affected.
|
||||
|
||||
This allows for a Lisp-like `condition system`:idx:\:
|
||||
|
||||
.. code-block:: nim
|
||||
var myFile = open("broken.txt", fmWrite)
|
||||
try:
|
||||
onRaise do (e: ref Exception)-> bool:
|
||||
if e of IOError:
|
||||
stdout.writeln "ok, writing to stdout instead"
|
||||
else:
|
||||
# do raise other exceptions:
|
||||
result = true
|
||||
myFile.writeln "writing to broken file"
|
||||
finally:
|
||||
myFile.close()
|
||||
|
||||
``onRaise`` can only *filter* raised exceptions, it cannot transform one
|
||||
exception into another. (Nor should ``onRaise`` raise an exception though
|
||||
this is currently not enforced.) This restriction keeps the exception tracking
|
||||
analysis sound.
|
||||
|
||||
|
||||
Exception hierarchy
|
||||
-------------------
|
||||
|
||||
The exception tree is defined in the `system <system.html>`_ module:
|
||||
|
||||
.. include:: exception_hierarchy_fragment.txt
|
||||
Loading…
Add table
Add a link
Reference in a new issue