Imported exceptions

It is possible to raise/catch imported C++ exceptions. Types imported using importcpp can be raised or caught. Exceptions are raised by value and caught by reference. Example:

  1. type
  2. CStdException {.importcpp: "std::exception", header: "<exception>", inheritable.} = object
  3. ## does not inherit from `RootObj`, so we use `inheritable` instead
  4. CRuntimeError {.requiresInit, importcpp: "std::runtime_error", header: "<stdexcept>".} = object of CStdException
  5. ## `CRuntimeError` has no default constructor => `requiresInit`
  6. proc what(s: CStdException): cstring {.importcpp: "((char *)#.what())".}
  7. proc initRuntimeError(a: cstring): CRuntimeError {.importcpp: "std::runtime_error(@)", constructor.}
  8. proc initStdException(): CStdException {.importcpp: "std::exception()", constructor.}
  9. proc fn() =
  10. let a = initRuntimeError("foo")
  11. doAssert $a.what == "foo"
  12. var b: cstring
  13. try: raise initRuntimeError("foo2")
  14. except CStdException as e:
  15. doAssert e is CStdException
  16. b = e.what()
  17. doAssert $b == "foo2"
  18. try: raise initStdException()
  19. except CStdException: discard
  20. try: raise initRuntimeError("foo3")
  21. except CRuntimeError as e:
  22. b = e.what()
  23. except CStdException:
  24. doAssert false
  25. doAssert $b == "foo3"
  26. fn()

Note: getCurrentException() and getCurrentExceptionMsg() are not available for imported exceptions from C++. One needs to use the except ImportedException as x: syntax and rely on functionality of the x object to get exception details.