Sfoglia il codice sorgente

Hide backend API errors from job search chat.

Show generic connection and search failure messages so OpenAI responses never expose keys or internal details to users.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 2 mesi fa
parent
commit
a596b41e00

+ 23 - 0
App for Indeed/Services/UserFacingErrorMessage.swift

@@ -0,0 +1,23 @@
+import Foundation
+
+/// Maps backend and network errors to short, safe copy for the UI.
+enum UserFacingErrorMessage {
+    static func jobSearchFailure(_ error: Error) -> String {
+        if let urlError = error as? URLError {
+            switch urlError.code {
+            case .notConnectedToInternet,
+                 .networkConnectionLost,
+                 .timedOut,
+                 .cannotFindHost,
+                 .cannotConnectToHost,
+                 .dnsLookupFailed:
+                return "We couldn't reach the server. Check your internet connection and try again."
+            case .cancelled:
+                return "The search was cancelled. Try again when you're ready."
+            default:
+                break
+            }
+        }
+        return "Something went wrong while searching. Please try again in a moment."
+    }
+}

+ 13 - 17
App for Indeed/Views/DashboardView.swift

@@ -2163,7 +2163,7 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
                     self.chatMessages.append(ChatMessage(role: "assistant", content: reply, attachedJobs: freshJobs.isEmpty ? nil : freshJobs))
                     self.appendChatBubble(text: reply, isUser: false, jobs: freshJobs)
                 case .failure(let error):
-                    self.appendChatBubble(text: error.localizedDescription, isUser: false)
+                    self.appendChatBubble(text: UserFacingErrorMessage.jobSearchFailure(error), isUser: false)
                 }
             }
         }
@@ -2920,7 +2920,7 @@ private final class OpenAIJobSearchService {
             completion(.failure(NSError(
                 domain: "OpenAIJobSearchService",
                 code: 1,
-                userInfo: [NSLocalizedDescriptionKey: "Missing API key. Set OPENAI_API_KEY in Xcode Build Settings."]
+                userInfo: [NSLocalizedDescriptionKey: "Job search is unavailable."]
             )))
             return
         }
@@ -2995,19 +2995,12 @@ private final class OpenAIJobSearchService {
                 return
             }
             if let http = response as? HTTPURLResponse, !(200...299).contains(http.statusCode) {
-                if let apiError = try? JSONDecoder().decode(OpenAIAPIErrorResponse.self, from: data) {
-                    completion(.failure(NSError(
-                        domain: "OpenAIJobSearchService",
-                        code: http.statusCode,
-                        userInfo: [NSLocalizedDescriptionKey: apiError.error.message]
-                    )))
-                } else {
-                    completion(.failure(NSError(
-                        domain: "OpenAIJobSearchService",
-                        code: http.statusCode,
-                        userInfo: [NSLocalizedDescriptionKey: "Job search request failed with status \(http.statusCode)."]
-                    )))
-                }
+                _ = try? JSONDecoder().decode(OpenAIAPIErrorResponse.self, from: data)
+                completion(.failure(NSError(
+                    domain: "OpenAIJobSearchService",
+                    code: http.statusCode,
+                    userInfo: [NSLocalizedDescriptionKey: "Job search request failed."]
+                )))
                 return
             }
             do {
@@ -3051,8 +3044,11 @@ private final class OpenAIJobSearchService {
         }
         if let status = root["status"] as? String {
             if status == "failed" {
-                let message = (root["error"] as? [String: Any])?["message"] as? String ?? "The search request failed."
-                throw NSError(domain: "OpenAIJobSearchService", code: 7, userInfo: [NSLocalizedDescriptionKey: message])
+                throw NSError(
+                    domain: "OpenAIJobSearchService",
+                    code: 7,
+                    userInfo: [NSLocalizedDescriptionKey: "The search request failed."]
+                )
             }
             if status == "incomplete",
                let details = root["incomplete_details"] as? [String: Any],