summary refs log tree commit diff stats
path: root/tests/exception/tcpp_imported_exc.nim
blob: c8349f7d5b505ca181c84bd17fd7e71683e6e57e (plain) (blame)
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)