summary refs log tree commit diff stats
path: root/doc/manual/exceptions.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/exceptions.txt')
-rw-r--r--doc/manual/exceptions.txt132
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