tcpp_imported_exc.nim 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. discard """
  2. matrix: "--mm:refc"
  3. targets: "cpp"
  4. output: '''
  5. caught as std::exception
  6. expected
  7. finally1
  8. finally2
  9. finally2
  10. 2
  11. expected
  12. finally 1
  13. finally 2
  14. expected
  15. cpp exception caught
  16. '''
  17. # doesn't work on macos 13 seemingly due to libc++ linking issue https://stackoverflow.com/a/77375947
  18. disabled: osx
  19. """
  20. type
  21. std_exception* {.importcpp: "std::exception", header: "<exception>".} = object
  22. std_runtime_error* {.importcpp: "std::runtime_error", header: "<stdexcept>".} = object
  23. std_string* {.importcpp: "std::string", header: "<string>".} = object
  24. proc constructStdString(s: cstring): std_string {.importcpp: "std::string(@)", constructor, header: "<string>".}
  25. proc constructRuntimeError(s: stdstring): std_runtime_error {.importcpp: "std::runtime_error(@)", constructor.}
  26. proc what(ex: std_runtime_error): cstring {.importcpp: "((char *)#.what())".}
  27. proc myexception =
  28. raise constructRuntimeError(constructStdString("cpp_exception"))
  29. try:
  30. myexception() # raise std::runtime_error
  31. except std_exception:
  32. echo "caught as std::exception"
  33. try:
  34. raise constructStdString("x")
  35. except std_exception:
  36. echo "should not happen"
  37. except:
  38. echo "expected"
  39. doAssert(getCurrentException() == nil)
  40. proc earlyReturn =
  41. try:
  42. try:
  43. myexception()
  44. finally:
  45. echo "finally1"
  46. except:
  47. return
  48. finally:
  49. echo "finally2"
  50. earlyReturn()
  51. doAssert(getCurrentException() == nil)
  52. try:
  53. block blk1:
  54. try:
  55. raise newException(ValueError, "mmm")
  56. except:
  57. break blk1
  58. except:
  59. echo "should not happen"
  60. finally:
  61. echo "finally2"
  62. doAssert(getCurrentException() == nil)
  63. #--------------------------------------
  64. # raise by pointer and also generic type
  65. type
  66. std_vector[T] {.importcpp"std::vector", header"<vector>".} = object
  67. proc newVector[T](len: int): ptr std_vector[T] {.importcpp: "new std::vector<'1>(@)".}
  68. proc deleteVector[T](v: ptr std_vector[T]) {.importcpp: "delete @; @ = NIM_NIL;".}
  69. proc len[T](v: std_vector[T]): uint {.importcpp: "size".}
  70. var v = newVector[int](2)
  71. try:
  72. try:
  73. try:
  74. raise v
  75. except ptr std_vector[int] as ex:
  76. echo len(ex[])
  77. raise newException(ValueError, "msg5")
  78. except:
  79. echo "should not happen"
  80. finally:
  81. deleteVector(v)
  82. except:
  83. echo "expected"
  84. doAssert(v == nil)
  85. doAssert(getCurrentException() == nil)
  86. #--------------------------------------
  87. # mix of Nim and imported exceptions
  88. try:
  89. try:
  90. try:
  91. raise newException(KeyError, "msg1")
  92. except KeyError:
  93. raise newException(ValueError, "msg2")
  94. except:
  95. echo "should not happen"
  96. finally:
  97. echo "finally 1"
  98. except:
  99. doAssert(getCurrentExceptionMsg() == "msg2")
  100. raise constructStdString("std::string")
  101. finally:
  102. echo "finally 2"
  103. except:
  104. echo "expected"
  105. doAssert(getCurrentException() == nil)
  106. try:
  107. try:
  108. myexception()
  109. except std_runtime_error as ex:
  110. echo "cpp exception caught"
  111. raise newException(ValueError, "rewritten " & $ex.what())
  112. except:
  113. doAssert(getCurrentExceptionMsg() == "rewritten cpp_exception")
  114. doAssert(getCurrentException() == nil)