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
|
discard """
targets: "cpp"
output: '''caught as std::exception
expected
finally1
finally2
finally2
2
expected
finally 1
finally 2
expected
cpp exception caught
'''
"""
type
std_exception* {.importcpp: "std::exception", header: "<exception>".} = object
std_runtime_error* {.importcpp: "std::runtime_error", header: "<stdexcept>".} = object
std_string* {.importcpp: "std::string", header: "<string>".} = object
proc constructStdString(s: cstring): std_string {.importcpp: "std::string(@)", constructor, header: "<string>".}
proc constructRuntimeError(s: stdstring): std_runtime_error {.importcpp: "std::runtime_error(@)", constructor.}
proc what(ex: std_runtime_error): cstring {.importcpp: "((char *)#.what())".}
proc myexception =
raise constructRuntimeError(constructStdString("cpp_exception"))
try:
myexception() # raise std::runtime_error
except std_exception:
echo "caught as std::exception"
try:
raise constructStdString("x")
except std_exception:
echo "should not happen"
except:
echo "expected"
doAssert(getCurrentException() == nil)
proc earlyReturn =
try:
try:
myexception()
finally:
echo "finally1"
except:
return
finally:
echo "finally2"
earlyReturn()
doAssert(getCurrentException() == nil)
try:
block blk1:
try:
raise newException(ValueError, "mmm")
except:
break blk1
except:
echo "should not happen"
finally:
echo "finally2"
doAssert(getCurrentException() == nil)
#--------------------------------------
# raise by pointer and also generic type
type
std_vector {.importcpp"std::vector", header"<vector>".} [T] = object
proc newVector[T](len: int): ptr std_vector[T] {.importcpp: "new std::vector<'1>(@)".}
proc deleteVector[T](v: ptr std_vector[T]) {.importcpp: "delete @; @ = NIM_NIL;".}
proc len[T](v: std_vector[T]): uint {.importcpp: "size".}
var v = newVector[int](2)
try:
try:
try:
raise v
except ptr std_vector[int] as ex:
echo len(ex[])
raise newException(ValueError, "msg5")
except:
echo "should not happen"
finally:
deleteVector(v)
except:
echo "expected"
doAssert(v == nil)
doAssert(getCurrentException() == nil)
#--------------------------------------
# mix of Nim and imported exceptions
try:
try:
try:
raise newException(KeyError, "msg1")
except KeyError:
raise newException(ValueError, "msg2")
except:
echo "should not happen"
finally:
echo "finally 1"
except:
doAssert(getCurrentExceptionMsg() == "msg2")
raise constructStdString("std::string")
finally:
echo "finally 2"
except:
echo "expected"
doAssert(getCurrentException() == nil)
try:
try:
myexception()
except std_runtime_error as ex:
echo "cpp exception caught"
raise newException(ValueError, "rewritten " & $ex.what())
except:
doAssert(getCurrentExceptionMsg() == "rewritten cpp_exception")
doAssert(getCurrentException() == nil)
|