diff --git a/Sources/CodexBarCore/OpenAIWeb/OpenAIDashboardNavigationDelegate.swift b/Sources/CodexBarCore/OpenAIWeb/OpenAIDashboardNavigationDelegate.swift index 0bf4e24b8..52ff42ecb 100644 --- a/Sources/CodexBarCore/OpenAIWeb/OpenAIDashboardNavigationDelegate.swift +++ b/Sources/CodexBarCore/OpenAIWeb/OpenAIDashboardNavigationDelegate.swift @@ -19,13 +19,26 @@ final class NavigationDelegate: NSObject, WKNavigationDelegate { } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { + if Self.shouldIgnoreNavigationError(error) { + self.completeOnce(.success(())) + return + } self.completeOnce(.failure(error)) } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { + if Self.shouldIgnoreNavigationError(error) { + self.completeOnce(.success(())) + return + } self.completeOnce(.failure(error)) } + nonisolated static func shouldIgnoreNavigationError(_ error: Error) -> Bool { + let nsError = error as NSError + return nsError.domain == NSURLErrorDomain && nsError.code == NSURLErrorCancelled + } + private func completeOnce(_ result: Result) { guard !self.hasCompleted else { return } self.hasCompleted = true diff --git a/Tests/CodexBarTests/OpenAIDashboardNavigationDelegateTests.swift b/Tests/CodexBarTests/OpenAIDashboardNavigationDelegateTests.swift new file mode 100644 index 000000000..0f27055f3 --- /dev/null +++ b/Tests/CodexBarTests/OpenAIDashboardNavigationDelegateTests.swift @@ -0,0 +1,36 @@ +import Foundation +import Testing +import WebKit +@testable import CodexBarCore + +@Suite +struct OpenAIDashboardNavigationDelegateTests { + @Test("ignores NSURLErrorCancelled") + func ignoresCancelledNavigationError() { + let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorCancelled) + #expect(NavigationDelegate.shouldIgnoreNavigationError(error)) + } + + @Test("does not ignore non-cancelled URL errors") + func doesNotIgnoreOtherURLErrors() { + let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorTimedOut) + #expect(!NavigationDelegate.shouldIgnoreNavigationError(error)) + } + + @MainActor + @Test("cancelled failures complete with success") + func cancelledFailureCompletesWithSuccess() { + let webView = WKWebView() + var result: Result? + let delegate = NavigationDelegate { result = $0 } + + delegate.webView(webView, didFail: nil, withError: NSError(domain: NSURLErrorDomain, code: NSURLErrorCancelled)) + + switch result { + case .success?: + #expect(Bool(true)) + default: + #expect(Bool(false)) + } + } +}