Skip to content

Commit 9c42e3f

Browse files
Ryan-Sheehandiederich
authored andcommitted
BridgeJS: fix codegen for async + throws exported methods
The render method handled isAsync and isThrows as mutually exclusive branches, so methods that were both async and throws only got the JSPromise.async wrapper without the explicit throws(JSException) type annotation on the closure. This caused the Swift compiler to infer throws(any Error) instead of throws(JSException), producing a build error. Add a new branch for the combined case that explicitly annotates the closure with `() async throws(JSException) [-> JSValue] in`. Made-with: Cursor
1 parent 0c4c45a commit 9c42e3f

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,19 @@ public class ExportSwift {
319319
func render(abiName: String) -> DeclSyntax {
320320
let body: CodeBlockItemListSyntax
321321
if effects.isAsync {
322+
// Explicit closure type annotation needed when throws is present
323+
// so Swift infers throws(JSException) instead of throws(any Error)
324+
// See: https://github.com/swiftlang/swift/issues/76165
325+
let closureHead: String
326+
if effects.isThrows {
327+
let hasReturn = self.body.contains { $0.description.contains("return ") }
328+
let ret = hasReturn ? " -> JSValue" : ""
329+
closureHead = " () async throws(JSException)\(ret) in"
330+
} else {
331+
closureHead = ""
332+
}
322333
body = """
323-
let ret = JSPromise.async {
334+
let ret = JSPromise.async {\(raw: closureHead)
324335
\(CodeBlockItemListSyntax(self.body))
325336
}.jsObject
326337
return ret.bridgeJSLowerReturn()

0 commit comments

Comments
 (0)