forked from nim-lang/Nim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexceptions.txt
158 lines (116 loc) · 4.03 KB
/
exceptions.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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).
Try expression
--------------
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")
defer: close(f)
f.write "abc"
f.write "def"
Is rewritten to:
.. code-block:: nim
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.
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).
Exception hierarchy
-------------------
The exception tree is defined in the `system <system.html>`_ module:
.. include:: exception_hierarchy_fragment.txt