diff options
Diffstat (limited to 'doc/manual/exceptions.txt')
-rw-r--r-- | doc/manual/exceptions.txt | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt new file mode 100644 index 000000000..ba2ea30a0 --- /dev/null +++ b/doc/manual/exceptions.txt @@ -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 |