Fix hardcoded user-facing strings — localize email fallbacks, API errors, AI parse messages
- Frontend: update extractApiError to check body.code first via i18n 'error.<code>' keys; add en/ro translations for cv_file_missing, captcha_verification_failed, request_cancelled - email-data migration: seed 6 fallback template keys (match N/A, subject label, unknown IP, job search results empty states for keywords/providers/location) - EmailApiEmailSender: replace "N/A", "Job", "Unknown" literals with template lookups - CvSearchEmailSender: replace "none detected", "none", "-" literals with template lookups - cv-matcher-data migration: seed parse-error.summary and parse-error.recommendation in AiPrompts - CvMatcherService: look up localized parse-error messages from AiPrompts before calling ParseResult Closes #53 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -115,7 +115,10 @@
|
||||
"cv.noItems": "No items yet.",
|
||||
"cv.strengths": "Strengths",
|
||||
"cv.gaps": "Gaps",
|
||||
"cv.evidence": "Supporting CV excerpts"
|
||||
"cv.evidence": "Supporting CV excerpts",
|
||||
"error.cv_file_missing": "Missing CV PDF.",
|
||||
"error.captcha_verification_failed": "Captcha verification failed.",
|
||||
"error.request_cancelled": "Request was cancelled."
|
||||
},
|
||||
ro: {
|
||||
"brand.subtitle": "prezentare inginerie AI",
|
||||
@@ -224,7 +227,10 @@
|
||||
"cv.noItems": "Niciun element.",
|
||||
"cv.strengths": "Puncte forte",
|
||||
"cv.gaps": "Lipsuri",
|
||||
"cv.evidence": "Fragmente relevante din CV"
|
||||
"cv.evidence": "Fragmente relevante din CV",
|
||||
"error.cv_file_missing": "Fișierul CV PDF lipsește.",
|
||||
"error.captcha_verification_failed": "Verificarea captcha a eșuat.",
|
||||
"error.request_cancelled": "Cererea a fost anulată."
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -52,6 +52,7 @@ function isValidEmail(value) {
|
||||
*
|
||||
* Rules:
|
||||
* - 429 (rate limit) → return rateLimitKey translation
|
||||
* - 4xx with known error code → look up 'error.<code>' in i18n dictionary first
|
||||
* - 4xx with error body → return server's error message (intentional feedback)
|
||||
* - 5xx or no body → return fallbackKey translation
|
||||
*
|
||||
@@ -65,8 +66,17 @@ function extractApiError(body, status, fallbackKey, rateLimitKey) {
|
||||
if (status === 429) {
|
||||
return window.MyAi.t(rateLimitKey || 'form.rateLimited');
|
||||
}
|
||||
var msg = body && (body.error || body.Error || body.title);
|
||||
return (status >= 400 && status < 500 && msg) ? msg : window.MyAi.t(fallbackKey);
|
||||
if (status >= 400 && status < 500) {
|
||||
// Prefer i18n translation keyed on the machine-readable error code
|
||||
if (body && body.code) {
|
||||
var codeKey = 'error.' + body.code;
|
||||
var translated = window.MyAi.t(codeKey);
|
||||
if (translated !== codeKey) return translated;
|
||||
}
|
||||
var msg = body && (body.error || body.Error || body.title);
|
||||
if (msg) return msg;
|
||||
}
|
||||
return window.MyAi.t(fallbackKey);
|
||||
}
|
||||
|
||||
// Expose helpers on window.MyAi for use by other scripts
|
||||
|
||||
Reference in New Issue
Block a user