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.txt97
1 files changed, 74 insertions, 23 deletions
diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt
index 7cad1c2b4..0010d5d09 100644
--- a/doc/manual/exceptions.txt
+++ b/doc/manual/exceptions.txt
@@ -47,36 +47,87 @@ the rest of the procedure - that is not within a ``finally`` clause -
 is not executed (if an exception occurs).
 
 
-Standalone except and finally statements
-----------------------------------------
+Try expression
+--------------
 
-``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:
+Try can also be used as an expression; the type of the ``try`` branch then
+needs to fit the types of ``except`` branches, but the type of the ``finally``
+branch always has to be ``void``:
+
+.. code-block:: nim
+  let x = try: parseInt("133a")
+          except: -1
+          finally: echo "hi"
+
+
+To prevent confusing code there is a parsing limitation; if the ``try``
+follows a ``(`` it has to be written as a one liner:
+
+.. code-block:: nim
+  let x = (try: parseInt("133a") except: -1)
+
+
+Except clauses
+--------------
+
+Within an ``except`` clause, it is possible to use
+``getCurrentException`` to retrieve the exception that has been
+raised:
+
+.. code-block:: nim
+  try:
+    # ...
+  except IOError:
+    let e = getCurrentException()
+    # Now use "e"
+
+Note that ``getCurrentException`` always returns a ``ref Exception``
+type. If a variable of the proper type is needed (in the example
+above, ``IOError``), one must convert it explicitly:
+
+.. code-block:: nim
+  try:
+    # ...
+  except IOError:
+    let e = (ref IOError)(getCurrentException())
+    # "e" is now of the proper type
+
+However, this is seldom needed. The most common case is to extract an
+error message from ``e``, and for such situations it is enough to use
+``getCurrentExceptionMsg``:
+
+.. code-block:: nim
+  try:
+    # ...
+  except IOError:
+    echo "I/O error: " & getCurrentExceptionMsg()
+
+
+Defer statement
+---------------
+
+Instead of a ``try finally`` statement a ``defer`` statement can be used.
+
+Any statements following the ``defer`` 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)
-  ...
+  defer: close(f)
+  f.write "abc"
+  f.write "def"
 
-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:
+Is rewritten to:
 
 .. 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
-
-Top level standalone ``finally`` or ``except`` statements are not supported
+  var f = open("numbers.txt")
+  try:
+    f.write "abc"
+    f.write "def"
+  finally:
+    close(f)
+
+Top level ``defer`` statements are not supported
 since it's unclear what such a statement should refer to.