swift icon indicating copy to clipboard operation
swift copied to clipboard

[cxx-interop] Errors/Exceptions crash the Swift runtime instead of being forwarded to C++

Open mrousavy opened this issue 1 year ago • 2 comments

Description

I'm bridging Swift classes to C++ to use them from C++.

One of my classes has a function that throws an error, but I haven't found a way to implement error throwing in Swift yet (other than through Optional results).

I tried multiple approaches:

Swift errors

enum SomeError: Error {
  case failed
}

public class MySwiftClass {
  public func throwError() throws {
    throw SomeError.failed
  }
}

^ the problem with this approach is that throwError() is no longer accessible from C++ once it has throws in it's method signature.

Obj-C errors

public class MySwiftClass {
  public func throwError() throws {
    let error = NSException(name: NSExceptionName("Failed"), reason: "This failed!")
    error.raise()
  }
}

^ the problem with this approach is that the exception cannot be propagated to C++, it will always be "unhandled"

image

C++ errors

namespace helpers {
  void throwCppError(std::string message) { throw std::runtime_error(message); }
}
public class MySwiftClass {
  public func throwError() throws {
    helpers.throwCppError("This failed!")
  }
}

^ the problem with this approach is the same as with Obj-C errors - they are not propagated to C++ and will always be "unhandled". I cannot wrap them in a try/catch in C++.

Reproduction

enum SomeError: Error {
  case failed
}

public class MySwiftClass {
  public func throwError() throws {
    throw SomeError.failed
  }
}

Expected behavior

I expect errors/exceptions to be propagated upwards to C++ so I can handle them from there.

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: arm64-apple-macosx14.0

Additional information

No response

mrousavy avatar Jul 17 '24 15:07 mrousavy

Calling Swift functions that throw is not yet supported from C++. Swift will not support throwing C++/ObjC exceptions correctly, so they will not be propagated to C++. C++/ObjC exceptions that are thrown in C++ and not caught right now trap in Swift. Ideally Swift would in the future support catching such exceptions when a call to C++ is made, but that's not yet supported.

hyp avatar Jul 17 '24 16:07 hyp

Thanks for your reply!

Swift will not support throwing C++/ObjC exceptions correctly, so they will not be propagated to C++. C++/ObjC exceptions that are thrown in C++ and not caught right now trap in Swift. Ideally Swift would in the future support catching such exceptions when a call to C++ is made, but that's not yet supported.

Is that something that's on some kind of roadmap? Throwing errors in Swift, and catching them in C++? Should I open a feature request / enhancement for this to track this, or can we use this issue here?

mrousavy avatar Jul 17 '24 17:07 mrousavy