diff options
Diffstat (limited to 'doc/manual/exceptions.txt')
-rw-r--r-- | doc/manual/exceptions.txt | 97 |
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. |