Просмотр исходного кода

fix(i18n): Correct translation fallback logic for embedding errors (#5574)

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
Daniel 5 месяцев назад
Родитель
Сommit
50598b22b5

+ 3 - 1
src/i18n/locales/ca/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Clau d'API no vàlida. Comproveu la vostra configuració de clau d'API.",
 		"invalidBaseUrl": "URL base no vàlida. Comproveu la vostra configuració d'URL.",
 		"invalidModel": "Model no vàlid. Comproveu la vostra configuració de model.",
-		"invalidResponse": "Resposta no vàlida del servei d'incrustació. Comproveu la vostra configuració."
+		"invalidResponse": "Resposta no vàlida del servei d'incrustació. Comproveu la vostra configuració.",
+		"apiKeyRequired": "Es requereix una clau d'API per a aquest incrustador",
+		"baseUrlRequired": "Es requereix una URL base per a aquest incrustador"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Falta la configuració d'OpenAI per crear l'embedder",

+ 3 - 1
src/i18n/locales/de/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Ungültiger API-Schlüssel. Bitte überprüfe deine API-Schlüssel-Konfiguration.",
 		"invalidBaseUrl": "Ungültige Basis-URL. Bitte überprüfe deine URL-Konfiguration.",
 		"invalidModel": "Ungültiges Modell. Bitte überprüfe deine Modellkonfiguration.",
-		"invalidResponse": "Ungültige Antwort vom Embedder-Dienst. Bitte überprüfe deine Konfiguration."
+		"invalidResponse": "Ungültige Antwort vom Embedder-Dienst. Bitte überprüfe deine Konfiguration.",
+		"apiKeyRequired": "API-Schlüssel ist für diesen Embedder erforderlich",
+		"baseUrlRequired": "Basis-URL ist für diesen Embedder erforderlich"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "OpenAI-Konfiguration fehlt für die Erstellung des Embedders",

+ 3 - 1
src/i18n/locales/en/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Invalid API key. Please check your API key configuration.",
 		"invalidBaseUrl": "Invalid base URL. Please check your URL configuration.",
 		"invalidModel": "Invalid model. Please check your model configuration.",
-		"invalidResponse": "Invalid response from embedder service. Please check your configuration."
+		"invalidResponse": "Invalid response from embedder service. Please check your configuration.",
+		"apiKeyRequired": "API key is required for this embedder",
+		"baseUrlRequired": "Base URL is required for this embedder"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "OpenAI configuration missing for embedder creation",

+ 3 - 1
src/i18n/locales/es/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Clave de API no válida. Comprueba la configuración de tu clave de API.",
 		"invalidBaseUrl": "URL base no válida. Comprueba la configuración de tu URL.",
 		"invalidModel": "Modelo no válido. Comprueba la configuración de tu modelo.",
-		"invalidResponse": "Respuesta no válida del servicio de embedder. Comprueba tu configuración."
+		"invalidResponse": "Respuesta no válida del servicio de embedder. Comprueba tu configuración.",
+		"apiKeyRequired": "Se requiere una clave de API para este embedder",
+		"baseUrlRequired": "Se requiere una URL base para este embedder"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Falta la configuración de OpenAI para crear el incrustador",

+ 3 - 1
src/i18n/locales/fr/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Clé API invalide. Veuillez vérifier votre configuration de clé API.",
 		"invalidBaseUrl": "URL de base invalide. Veuillez vérifier votre configuration d'URL.",
 		"invalidModel": "Modèle invalide. Veuillez vérifier votre configuration de modèle.",
-		"invalidResponse": "Réponse invalide du service d'embedder. Veuillez vérifier votre configuration."
+		"invalidResponse": "Réponse invalide du service d'embedder. Veuillez vérifier votre configuration.",
+		"apiKeyRequired": "Une clé API est requise pour cet embedder.",
+		"baseUrlRequired": "Une URL de base est requise pour cet embedder"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Configuration OpenAI manquante pour la création de l'embedder",

+ 3 - 1
src/i18n/locales/hi/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "अमान्य एपीआई कुंजी। कृपया अपनी एपीआई कुंजी कॉन्फ़िगरेशन जांचें।",
 		"invalidBaseUrl": "अमान्य बेस यूआरएल। कृपया अपनी यूआरएल कॉन्फ़िगरेशन जांचें।",
 		"invalidModel": "अमान्य मॉडल। कृपया अपनी मॉडल कॉन्फ़िगरेशन जांचें।",
-		"invalidResponse": "एम्बेडर सेवा से अमान्य प्रतिक्रिया। कृपया अपनी कॉन्फ़िगरेशन जांचें।"
+		"invalidResponse": "एम्बेडर सेवा से अमान्य प्रतिक्रिया। कृपया अपनी कॉन्फ़िगरेशन जांचें।",
+		"apiKeyRequired": "इस एम्बेडर के लिए API कुंजी आवश्यक है।",
+		"baseUrlRequired": "इस एम्बेडर के लिए बेस यूआरएल आवश्यक है"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "एम्बेडर बनाने के लिए OpenAI कॉन्फ़िगरेशन गायब है",

+ 3 - 1
src/i18n/locales/id/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Kunci API tidak valid. Silakan periksa konfigurasi kunci API Anda.",
 		"invalidBaseUrl": "URL dasar tidak valid. Silakan periksa konfigurasi URL Anda.",
 		"invalidModel": "Model tidak valid. Silakan periksa konfigurasi model Anda.",
-		"invalidResponse": "Respons tidak valid dari layanan embedder. Silakan periksa konfigurasi Anda."
+		"invalidResponse": "Respons tidak valid dari layanan embedder. Silakan periksa konfigurasi Anda.",
+		"apiKeyRequired": "Kunci API diperlukan untuk embedder ini",
+		"baseUrlRequired": "URL dasar diperlukan untuk embedder ini"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Konfigurasi OpenAI tidak ada untuk membuat embedder",

+ 3 - 1
src/i18n/locales/it/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Chiave API non valida. Controlla la configurazione della tua chiave API.",
 		"invalidBaseUrl": "URL di base non valido. Controlla la configurazione del tuo URL.",
 		"invalidModel": "Modello non valido. Controlla la configurazione del tuo modello.",
-		"invalidResponse": "Risposta non valida dal servizio embedder. Controlla la tua configurazione."
+		"invalidResponse": "Risposta non valida dal servizio embedder. Controlla la tua configurazione.",
+		"apiKeyRequired": "È richiesta una chiave API per questo embedder",
+		"baseUrlRequired": "È richiesto un URL di base per questo embedder"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Configurazione OpenAI mancante per la creazione dell'embedder",

+ 3 - 1
src/i18n/locales/ja/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "無効なAPIキーです。APIキー構成を確認してください。",
 		"invalidBaseUrl": "無効なベースURLです。URL構成を確認してください。",
 		"invalidModel": "無効なモデルです。モデル構成を確認してください。",
-		"invalidResponse": "エンベッダーサービスからの無効な応答です。設定を確認してください。"
+		"invalidResponse": "エンベッダーサービスからの無効な応答です。設定を確認してください。",
+		"apiKeyRequired": "このエンベッダーにはAPIキーが必要です。",
+		"baseUrlRequired": "このエンベッダーにはベースURLが必要です"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "エンベッダー作成のためのOpenAI設定がありません",

+ 3 - 1
src/i18n/locales/ko/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "잘못된 API 키입니다. API 키 구성을 확인하세요.",
 		"invalidBaseUrl": "잘못된 기본 URL입니다. URL 구성을 확인하세요.",
 		"invalidModel": "잘못된 모델입니다. 모델 구성을 확인하세요.",
-		"invalidResponse": "임베더 서비스에서 잘못된 응답이 왔습니다. 구성을 확인하세요."
+		"invalidResponse": "임베더 서비스에서 잘못된 응답이 왔습니다. 구성을 확인하세요.",
+		"apiKeyRequired": "이 임베더에는 API 키가 필요합니다",
+		"baseUrlRequired": "이 임베더에는 기본 URL이 필요합니다"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "임베더 생성을 위한 OpenAI 구성이 누락되었습니다",

+ 3 - 1
src/i18n/locales/nl/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Ongeldige API-sleutel. Controleer je API-sleutelconfiguratie.",
 		"invalidBaseUrl": "Ongeldige basis-URL. Controleer je URL-configuratie.",
 		"invalidModel": "Ongeldig model. Controleer je modelconfiguratie.",
-		"invalidResponse": "Ongeldige reactie van embedder-service. Controleer je configuratie."
+		"invalidResponse": "Ongeldige reactie van embedder-service. Controleer je configuratie.",
+		"apiKeyRequired": "API-sleutel is vereist voor deze embedder",
+		"baseUrlRequired": "Basis-URL is vereist voor deze embedder"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "OpenAI-configuratie ontbreekt voor het maken van embedder",

+ 3 - 1
src/i18n/locales/pl/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Nieprawidłowy klucz API. Sprawdź konfigurację klucza API.",
 		"invalidBaseUrl": "Nieprawidłowy podstawowy adres URL. Sprawdź konfigurację adresu URL.",
 		"invalidModel": "Nieprawidłowy model. Sprawdź konfigurację modelu.",
-		"invalidResponse": "Nieprawidłowa odpowiedź z usługi embedder. Sprawdź swoją konfigurację."
+		"invalidResponse": "Nieprawidłowa odpowiedź z usługi embedder. Sprawdź swoją konfigurację.",
+		"apiKeyRequired": "Klucz API jest wymagany dla tego embeddera",
+		"baseUrlRequired": "Podstawowy adres URL jest wymagany dla tego embeddera"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Brak konfiguracji OpenAI do utworzenia embeddera",

+ 3 - 1
src/i18n/locales/pt-BR/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Chave de API inválida. Verifique sua configuração de chave de API.",
 		"invalidBaseUrl": "URL base inválida. Verifique sua configuração de URL.",
 		"invalidModel": "Modelo inválido. Verifique a configuração do seu modelo.",
-		"invalidResponse": "Resposta inválida do serviço de embedder. Verifique sua configuração."
+		"invalidResponse": "Resposta inválida do serviço de embedder. Verifique sua configuração.",
+		"apiKeyRequired": "A chave de API é necessária para este embedder",
+		"baseUrlRequired": "A URL base é necessária para este embedder"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Configuração do OpenAI ausente para criação do embedder",

+ 3 - 1
src/i18n/locales/ru/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Неверный ключ API. Проверьте конфигурацию ключа API.",
 		"invalidBaseUrl": "Неверный базовый URL. Проверьте конфигурацию URL.",
 		"invalidModel": "Неверная модель. Проверьте конфигурацию модели.",
-		"invalidResponse": "Неверный ответ от службы embedder. Проверьте вашу конфигурацию."
+		"invalidResponse": "Неверный ответ от службы embedder. Проверьте вашу конфигурацию.",
+		"apiKeyRequired": "Для этого встраивателя требуется ключ API",
+		"baseUrlRequired": "Для этого встраивателя требуется базовый URL"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Отсутствует конфигурация OpenAI для создания эмбеддера",

+ 3 - 1
src/i18n/locales/tr/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Geçersiz API anahtarı. Lütfen API anahtarı yapılandırmanızı kontrol edin.",
 		"invalidBaseUrl": "Geçersiz temel URL. Lütfen URL yapılandırmanızı kontrol edin.",
 		"invalidModel": "Geçersiz model. Lütfen model yapılandırmanızı kontrol edin.",
-		"invalidResponse": "Embedder hizmetinden geçersiz yanıt. Lütfen yapılandırmanızı kontrol edin."
+		"invalidResponse": "Embedder hizmetinden geçersiz yanıt. Lütfen yapılandırmanızı kontrol edin.",
+		"apiKeyRequired": "Bu gömücü için API anahtarı gereklidir",
+		"baseUrlRequired": "Bu gömücü için temel URL gereklidir"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Gömücü oluşturmak için OpenAI yapılandırması eksik",

+ 3 - 1
src/i18n/locales/vi/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "Khóa API không hợp lệ. Vui lòng kiểm tra cấu hình khóa API của bạn.",
 		"invalidBaseUrl": "URL cơ sở không hợp lệ. Vui lòng kiểm tra cấu hình URL của bạn.",
 		"invalidModel": "Mô hình không hợp lệ. Vui lòng kiểm tra cấu hình mô hình của bạn.",
-		"invalidResponse": "Phản hồi không hợp lệ từ dịch vụ embedder. Vui lòng kiểm tra cấu hình của bạn."
+		"invalidResponse": "Phản hồi không hợp lệ từ dịch vụ embedder. Vui lòng kiểm tra cấu hình của bạn.",
+		"apiKeyRequired": "Cần có khóa API cho trình nhúng này",
+		"baseUrlRequired": "Cần có URL cơ sở cho trình nhúng này"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "Thiếu cấu hình OpenAI để tạo embedder",

+ 3 - 1
src/i18n/locales/zh-CN/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "API 密钥无效。请检查您的 API 密钥配置。",
 		"invalidBaseUrl": "基础 URL 无效。请检查您的 URL 配置。",
 		"invalidModel": "模型无效。请检查您的模型配置。",
-		"invalidResponse": "嵌入服务响应无效。请检查您的配置。"
+		"invalidResponse": "嵌入服务响应无效。请检查您的配置。",
+		"apiKeyRequired": "此嵌入器需要 API 密钥",
+		"baseUrlRequired": "此嵌入器需要基础 URL"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "创建嵌入器缺少 OpenAI 配置",

+ 3 - 1
src/i18n/locales/zh-TW/embeddings.json

@@ -37,7 +37,9 @@
 		"invalidApiKey": "無效的 API 金鑰。請檢查您的 API 金鑰組態。",
 		"invalidBaseUrl": "無效的基礎 URL。請檢查您的 URL 組態。",
 		"invalidModel": "無效的模型。請檢查您的模型組態。",
-		"invalidResponse": "內嵌服務回應無效。請檢查您的組態。"
+		"invalidResponse": "內嵌服務回應無效。請檢查您的組態。",
+		"apiKeyRequired": "此嵌入器需要 API 金鑰",
+		"baseUrlRequired": "此嵌入器需要基礎 URL"
 	},
 	"serviceFactory": {
 		"openAiConfigMissing": "建立嵌入器缺少 OpenAI 設定",

+ 3 - 3
src/services/code-index/embedders/__tests__/gemini.spec.ts

@@ -34,9 +34,9 @@ describe("GeminiEmbedder", () => {
 
 		it("should throw error when API key is not provided", () => {
 			// Act & Assert
-			expect(() => new GeminiEmbedder("")).toThrow("API key is required for Gemini embedder")
-			expect(() => new GeminiEmbedder(null as any)).toThrow("API key is required for Gemini embedder")
-			expect(() => new GeminiEmbedder(undefined as any)).toThrow("API key is required for Gemini embedder")
+			expect(() => new GeminiEmbedder("")).toThrow("validation.apiKeyRequired")
+			expect(() => new GeminiEmbedder(null as any)).toThrow("validation.apiKeyRequired")
+			expect(() => new GeminiEmbedder(undefined as any)).toThrow("validation.apiKeyRequired")
 		})
 	})
 

+ 3 - 3
src/services/code-index/embedders/__tests__/openai-compatible.spec.ts

@@ -80,19 +80,19 @@ describe("OpenAICompatibleEmbedder", () => {
 
 		it("should throw error when baseUrl is missing", () => {
 			expect(() => new OpenAICompatibleEmbedder("", testApiKey, testModelId)).toThrow(
-				"Base URL is required for OpenAI Compatible embedder",
+				"embeddings:validation.baseUrlRequired",
 			)
 		})
 
 		it("should throw error when apiKey is missing", () => {
 			expect(() => new OpenAICompatibleEmbedder(testBaseUrl, "", testModelId)).toThrow(
-				"API key is required for OpenAI Compatible embedder",
+				"embeddings:validation.apiKeyRequired",
 			)
 		})
 
 		it("should throw error when both baseUrl and apiKey are missing", () => {
 			expect(() => new OpenAICompatibleEmbedder("", "", testModelId)).toThrow(
-				"Base URL is required for OpenAI Compatible embedder",
+				"embeddings:validation.baseUrlRequired",
 			)
 		})
 	})

+ 2 - 1
src/services/code-index/embedders/gemini.ts

@@ -1,6 +1,7 @@
 import { OpenAICompatibleEmbedder } from "./openai-compatible"
 import { IEmbedder, EmbeddingResponse, EmbedderInfo } from "../interfaces/embedder"
 import { GEMINI_MAX_ITEM_TOKENS } from "../constants"
+import { t } from "../../../i18n"
 
 /**
  * Gemini embedder implementation that wraps the OpenAI Compatible embedder
@@ -23,7 +24,7 @@ export class GeminiEmbedder implements IEmbedder {
 	 */
 	constructor(apiKey: string) {
 		if (!apiKey) {
-			throw new Error("API key is required for Gemini embedder")
+			throw new Error(t("embeddings:validation.apiKeyRequired"))
 		}
 
 		// Create an OpenAI Compatible embedder with Gemini's fixed configuration

+ 2 - 2
src/services/code-index/embedders/openai-compatible.ts

@@ -45,10 +45,10 @@ export class OpenAICompatibleEmbedder implements IEmbedder {
 	 */
 	constructor(baseUrl: string, apiKey: string, modelId?: string, maxItemTokens?: number) {
 		if (!baseUrl) {
-			throw new Error("Base URL is required for OpenAI Compatible embedder")
+			throw new Error(t("embeddings:validation.baseUrlRequired"))
 		}
 		if (!apiKey) {
-			throw new Error("API key is required for OpenAI Compatible embedder")
+			throw new Error(t("embeddings:validation.apiKeyRequired"))
 		}
 
 		this.baseUrl = baseUrl

+ 2 - 9
src/services/code-index/manager.ts

@@ -263,15 +263,8 @@ export class CodeIndexManager {
 		const validationResult = await this._serviceFactory.validateEmbedder(embedder)
 		if (!validationResult.valid) {
 			const errorMessage = validationResult.error || "Embedder configuration validation failed"
-			// Always attempt translation, use original as fallback
-			let translatedMessage = t(errorMessage)
-			// If translation returns a different value (stripped namespace), use original
-			if (translatedMessage !== errorMessage && !translatedMessage.includes(":")) {
-				translatedMessage = errorMessage
-			}
-
-			this._stateManager.setSystemState("Error", translatedMessage)
-			throw new Error(translatedMessage)
+			this._stateManager.setSystemState("Error", errorMessage)
+			throw new Error(errorMessage)
 		}
 
 		// (Re)Initialize orchestrator

+ 8 - 8
src/services/code-index/shared/validation-helpers.ts

@@ -28,16 +28,16 @@ export function getErrorMessageForStatus(status: number | undefined, embedderTyp
 	switch (status) {
 		case 401:
 		case 403:
-			return "embeddings:validation.authenticationFailed"
+			return t("embeddings:validation.authenticationFailed")
 		case 404:
 			return embedderType === "openai"
-				? "embeddings:validation.modelNotAvailable"
-				: "embeddings:validation.invalidEndpoint"
+				? t("embeddings:validation.modelNotAvailable")
+				: t("embeddings:validation.invalidEndpoint")
 		case 429:
-			return "embeddings:validation.serviceUnavailable"
+			return t("embeddings:validation.serviceUnavailable")
 		default:
 			if (status && status >= 400 && status < 600) {
-				return "embeddings:validation.configurationError"
+				return t("embeddings:validation.configurationError")
 			}
 			return undefined
 	}
@@ -138,11 +138,11 @@ export function handleValidationError(
 			errorMessage.includes("HTTP 0:") ||
 			errorMessage === "No response"
 		) {
-			return { valid: false, error: "embeddings:validation.connectionFailed" }
+			return { valid: false, error: t("embeddings:validation.connectionFailed") }
 		}
 
 		if (errorMessage.includes("Failed to parse response JSON")) {
-			return { valid: false, error: "embeddings:validation.invalidResponse" }
+			return { valid: false, error: t("embeddings:validation.invalidResponse") }
 		}
 	}
 
@@ -152,7 +152,7 @@ export function handleValidationError(
 	}
 
 	// Fallback to generic error
-	return { valid: false, error: "embeddings:validation.configurationError" }
+	return { valid: false, error: t("embeddings:validation.configurationError") }
 }
 
 /**