From cf82720b88cc05bde3ca539676f69f919883fdce Mon Sep 17 00:00:00 2001 From: Rune Olsen Date: Wed, 19 Aug 2026 13:53:06 +0200 Subject: [PATCH] Fix Sendable warning in AppleMailError by dropping the NSDictionary payload appleScriptError carried the raw NSDictionary from NSAppleScript's error out-param, which isn't Sendable and got flagged once the type crossed an async boundary. Extract just the two fields actually used (errorNumber, errorMessage) into plain Int/String instead. --- oAI/Services/AppleMailService.swift | 20 ++++++++++---------- oAITests/AppleMailServiceTests.swift | 18 +++--------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/oAI/Services/AppleMailService.swift b/oAI/Services/AppleMailService.swift index ad7a6fd..a266f03 100644 --- a/oAI/Services/AppleMailService.swift +++ b/oAI/Services/AppleMailService.swift @@ -37,9 +37,9 @@ struct MailSearchResult: Sendable, Equatable { let attachmentCount: String } -enum AppleMailError: Error { +enum AppleMailError: Error, Sendable { case scriptNotCompiled - case appleScriptError(NSDictionary) + case appleScriptError(number: Int, message: String) } @Observable @@ -320,7 +320,9 @@ final class AppleMailService { var errorDict: NSDictionary? let result = script.executeAppleEvent(event, error: &errorDict) if let errorDict { - continuation.resume(returning: .failure(.appleScriptError(errorDict))) + let number = (errorDict[NSAppleScript.errorNumber] as? Int) ?? 0 + let message = (errorDict[NSAppleScript.errorMessage] as? String) ?? "Unknown error" + continuation.resume(returning: .failure(.appleScriptError(number: number, message: message))) } else { continuation.resume(returning: .success(result)) } @@ -358,9 +360,7 @@ final class AppleMailService { return results } - nonisolated static func mapAppleScriptError(_ errorInfo: NSDictionary) -> String { - let number = (errorInfo[NSAppleScript.errorNumber] as? Int) ?? 0 - let message = (errorInfo[NSAppleScript.errorMessage] as? String) ?? "Unknown error" + nonisolated static func mapAppleScriptError(number: Int, message: String) -> String { switch number { case -1743: return "Confab is not authorized to control Mail.app. Grant access in System Settings \u{2192} Privacy & Security \u{2192} Automation \u{2192} Confab \u{2192} Mail, then try again." @@ -375,8 +375,8 @@ final class AppleMailService { switch error { case .scriptNotCompiled: return ["error": "Mail integration failed to initialize (AppleScript compile error)."] - case .appleScriptError(let dict): - return ["error": mapAppleScriptError(dict)] + case .appleScriptError(let number, let message): + return ["error": mapAppleScriptError(number: number, message: message)] } } @@ -629,8 +629,8 @@ final class AppleMailService { switch error { case .scriptNotCompiled: message = "Mail integration failed to initialize (AppleScript compile error)." - case .appleScriptError(let dict): - message = Self.mapAppleScriptError(dict) + case .appleScriptError(let number, let msg): + message = Self.mapAppleScriptError(number: number, message: msg) } return .failure(NSError(domain: "AppleMailService", code: 1, userInfo: [NSLocalizedDescriptionKey: message])) } diff --git a/oAITests/AppleMailServiceTests.swift b/oAITests/AppleMailServiceTests.swift index a55b9fb..90510bc 100644 --- a/oAITests/AppleMailServiceTests.swift +++ b/oAITests/AppleMailServiceTests.swift @@ -85,32 +85,20 @@ struct AppleMailServiceTests { @Test("mapAppleScriptError maps -1743 to an Automation-permission message") func mapsNotAuthorizedError() { - let dict: NSDictionary = [ - NSAppleScript.errorNumber: -1743, - NSAppleScript.errorMessage: "Not authorized" - ] - let message = AppleMailService.mapAppleScriptError(dict) + let message = AppleMailService.mapAppleScriptError(number: -1743, message: "Not authorized") #expect(message.contains("not authorized")) #expect(message.contains("Automation")) } @Test("mapAppleScriptError maps -600 to a Mail-not-available message") func mapsApplicationNotRunningError() { - let dict: NSDictionary = [ - NSAppleScript.errorNumber: -600, - NSAppleScript.errorMessage: "Application isn't running" - ] - let message = AppleMailService.mapAppleScriptError(dict) + let message = AppleMailService.mapAppleScriptError(number: -600, message: "Application isn't running") #expect(message.contains("not available")) } @Test("mapAppleScriptError falls back to a generic formatted message for unknown error numbers") func mapsGenericError() { - let dict: NSDictionary = [ - NSAppleScript.errorNumber: -1234, - NSAppleScript.errorMessage: "Something odd happened" - ] - let message = AppleMailService.mapAppleScriptError(dict) + let message = AppleMailService.mapAppleScriptError(number: -1234, message: "Something odd happened") #expect(message.contains("-1234")) #expect(message.contains("Something odd happened")) }