Skip to content

Conversation

@BhagyeshPatil2004
Copy link

@BhagyeshPatil2004 BhagyeshPatil2004 commented Jan 24, 2026

Error Message & Validation Localization Engine

This PR adds a community demo under /community that showcases how Lingo.dev can be used to dynamically localize backend error and validation messages.

This submission is part of the community demo initiative.
Closes #1761

🎯 Overview

A production-grade demo showcasing automatic backend error localization. This addresses a common pain point: most applications translate UI labels but leave backend errors in English.

🚀 What This Demo Does

This project demonstrates dynamic backend error localization - intercepting validation errors before they reach the client and translating them to the user's preferred language in real-time.

Key Features:

  • Automatic Language Detection - Supports both ?lang=xx query parameters and Accept-Language headers
  • Real-time Translation - Powered by Lingo.dev SDK with AI-driven localization
  • Multi-language Support - Tested with English, Spanish, French, German, Hindi, and Japanese
  • Production-Ready Pattern - Clean middleware architecture that scales to any language
  • Beautiful UI - Modern frontend with gradient design and smooth animations
  • Zero Manual Translation Files - No hardcoded translations needed

🛠️ Tech Stack

  • Backend: Node.js + Express
  • Localization: Lingo.dev SDK (lingo.dev/sdk)
  • Frontend: Vanilla HTML/CSS/JS (framework-agnostic)

📂 Project Structure

community/error-localization-engine
├── server.js # Express server with CORS
├── lingoClient.js # Lingo.dev SDK wrapper
├── middleware/localizer.js # Language detection middleware
├── routes/auth.js # Auth endpoints with validation
└── public/ # Frontend UI
‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ├── index.html
‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ├── styles.css
‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ └── app.js

🧪 How to Test

  1. npm install
  2. Add API key to .env
  3. npm start
  4. Open http://localhost:3000
  5. Select a language and try invalid inputs!

💡 Why This Matters

Most developers focus on UI localization but forget about backend errors. This demo shows a scalable pattern for:

  • Centralizing error messages
  • Dynamic localization without manual translation files
  • Maintaining consistency across all user touchpoints

Demo Screenshots :

image‎ ‎ ‎ ‎ ‎ ‎

Screenshot 2026-01-24 213936 ‎ ‎ ‎ ‎ ‎ ‎ Screenshot 2026-01-24 213704 ‎ ‎ ‎ ‎ ‎ ‎ Screenshot 2026-01-24 213809 ‎ ‎ ‎ ‎ ‎ ‎ Screenshot 2026-01-24 214019

Summary by CodeRabbit

Release Notes

  • New Features

    • Added demo application with language selection dropdown and signup form.
    • Error and validation messages now display in user-selected language.
    • Language selection available via dropdown, query parameter, or Accept-Language header.
  • Documentation

    • Added comprehensive project setup and API testing guide.
  • Chores

    • Added environment configuration and project dependencies.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

📝 Walkthrough

Walkthrough

This PR introduces a complete error localization demo application in the community/ directory showcasing how to integrate Lingo.dev for localizing backend validation and error messages in a Node.js/Express application, with language negotiation via query parameters or HTTP headers.

Changes

Cohort / File(s) Summary
Configuration & Setup
.env.example, .gitignore, package.json
Added environment template with API key and port placeholders; configured Git ignore rules for dependencies, logs, and OS metadata; established project manifest with Express, Lingo.dev SDK, and development dependencies.
Core Application Logic
server.js, lingoClient.js
Created Express server with CORS, JSON parsing, and static file serving; implemented Lingo.dev integration module with localizeError() function supporting both API mode (live translation) and mock mode (locale prefix injection) with fallback error handling.
Middleware & Routing
middleware/localizer.js, routes/auth.js
Added language extraction middleware resolving target language from query parameter (lang), Accept-Language header, or default fallback; implemented signup and login endpoints with email/password validation and full localization of all error and success responses.
Frontend Assets
public/index.html, public/app.js, public/styles.css
Created HTML signup form with language selector (6 languages), email/password inputs, and response display container; implemented form submission with language forwarding and error/success message handling; added complete responsive styling with gradient backgrounds, animations, and mobile adjustments.
Documentation & Verification
README.md, verify.js
Added comprehensive README describing the demo's purpose, setup instructions, API examples, and localization test cases; introduced automated verification script performing three API tests validating Spanish, French, and English localization markers in responses.

Sequence Diagram

sequenceDiagram
    participant Client as User/Browser
    participant Frontend as Frontend App
    participant Server as Express Server
    participant Localizer as Localizer Middleware
    participant AuthRoute as Auth Route
    participant LingoClient as Lingo Client
    participant LingoAPI as Lingo.dev API

    Client->>Frontend: Select language & submit signup form
    Frontend->>Server: POST /api/auth/signup?lang=es (email, password)
    
    Server->>Localizer: Middleware processes request
    Localizer->>Localizer: Extract language from query/header
    Localizer->>Server: Attach req.targetLang = 'es'
    
    Server->>AuthRoute: Route handler validates input
    AuthRoute->>AuthRoute: Validate email & password format
    
    alt Validation fails
        AuthRoute->>LingoClient: localizeError(errorMsg, 'es')
        LingoClient->>LingoAPI: POST localize (message, targetLocale='es')
        LingoAPI-->>LingoClient: Translated error
        LingoClient-->>AuthRoute: Localized error response
        AuthRoute-->>Server: 400/409 + localized error
    else Validation passes
        AuthRoute->>LingoClient: localizeError(successMsg, 'es')
        LingoClient->>LingoAPI: POST localize (message, targetLocale='es')
        LingoAPI-->>LingoClient: Translated success message
        LingoClient-->>AuthRoute: Localized success response
        AuthRoute-->>Server: 200 + localized success message
    end
    
    Server-->>Frontend: JSON response (localized content)
    Frontend-->>Client: Display localized error/success message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Whisker-twitching with glee...

Error messages dance in Spanish, French, and more,
Backend tales told in each tongue at the door,
Lingo.dev translates our validation cheer,
A demo of localization, crystal clear! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main addition: a community demo for error message localization using Lingo.dev, with issue reference.
Description check ✅ Passed The description provides comprehensive context including overview, features, tech stack, structure, testing instructions, and screenshots; however, it does not follow the repository's template structure with formal sections.
Linked Issues check ✅ Passed The PR meets all coding requirements from issue #1761: demo added under /community/error-localization-engine with comprehensive README, run instructions, and highlighted Lingo.dev SDK integration features.
Out of Scope Changes check ✅ Passed All changes are within scope: configuration files, documentation, frontend UI, backend server, middleware, and routes—all directly support the error localization engine demo objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@community/error-localization-engine/middleware/localizer.js`:
- Around line 7-20: Normalize the derived lang before assigning req.targetLang:
if req.query.lang is an array or object, coerce it to a string by taking the
first element/value; when parsing req.headers['accept-language'], split on ','
then drop any quality suffix by splitting on ';' and trimming the result;
lowercase or otherwise normalize the token (e.g., toLowerCase()) and optionally
validate it against a simple BCP-47-ish pattern before assigning to
req.targetLang; finally fall back to 'en' if the normalized value is empty or
invalid. Ensure you update the logic around req.query.lang, acceptLang (the
variable from req.headers['accept-language']), and the final assignment to
req.targetLang.

In `@community/error-localization-engine/README.md`:
- Around line 40-90: Add a short clarifying note under the "🧪 Testing the API"
section (before the examples for English/Spanish/French) that explains if
LINGO_API_KEY is not set the server runs in mock mode and localized responses
may be mock-prefixed (e.g., "[es] ..." or "[fr] ...") rather than fully
translated; mention that real translations are returned when LINGO_API_KEY is
provided and that language detection still follows the `?lang=xx` query
parameter and `Accept-Language` header priority rules already described.

In `@community/error-localization-engine/routes/auth.js`:
- Around line 73-78: The token is being passed into localizeError (see
localizeError call creating successMsg) which may try to translate it; change
the flow so you first call localizeError with only translatable fields (e.g.,
message) to get the localized payload, then attach the non-translatable token
field (e.g., token: "fake-jwt-token-123456") onto the returned object before
sending res.json, ensuring localizeError is not given the token.

In `@community/error-localization-engine/verify.js`:
- Around line 1-72: The script currently hardcodes port 3000 and always expects
mock-prefixed localization; update runTests to require('dotenv').config(), build
baseURL using const port = process.env.PORT || 3000 and const baseURL =
`http://127.0.0.1:${port}/api/auth`, and detect mock mode via a boolean like
const isMock = !process.env.LINGO_API_KEY || process.env.LINGO_API_KEY ===
'your_lingo_api_key_here'; then adjust the localization assertions (in the POST
/signup error checks and success check) to only expect the mock prefix
'[es]'/'[fr]' when isMock is true, otherwise validate that translated messages
exist without assuming the mock prefix.
🧹 Nitpick comments (4)
community/error-localization-engine/package.json (1)

6-9: Declare a minimum Node version for node --watch.

The dev script depends on node --watch, which isn’t available in older Node LTS. Consider adding an engines.node constraint (or a fallback dev script) to prevent confusing runtime errors.

♻️ Suggested adjustment
   "scripts": {
     "start": "node server.js",
     "dev": "node --watch server.js"
   },
+  "engines": {
+    "node": ">=18.11"
+  },
   "dependencies": {
community/error-localization-engine/server.js (1)

29-34: Move dynamic require to module level.

The require('./lingoClient') inside the route handler is evaluated on every request. Move it to the top with other imports for efficiency.

Suggested fix
 const localizer = require('./middleware/localizer');
 const authRoutes = require('./routes/auth');
+const { localizeError } = require('./lingoClient');
 
 const app = express();

Then update the route:

 // Root endpoint
 app.get('/', async (req, res) => {
-    const { localizeError } = require('./lingoClient');
     const msg = await localizeError("Welcome to the Error Localization Engine Demo API!", req.targetLang);
     res.send(msg);
 });
community/error-localization-engine/public/app.js (1)

17-24: Consider encoding the language parameter.

While the current language values (en, es, fr, de, hi, ja) are safe, using encodeURIComponent is a good defensive practice for query parameters.

Suggested fix
-        const response = await fetch(`/api/auth/signup?lang=${language}`, {
+        const response = await fetch(`/api/auth/signup?lang=${encodeURIComponent(language)}`, {
community/error-localization-engine/lingoClient.js (1)

32-42: Mock mode doesn't handle nested objects.

The mock translation only processes top-level string values. Nested objects are copied as-is, which may produce inconsistent behavior between mock and API modes. This is acceptable for the demo's use case (flat error objects), but worth documenting.

For a more robust mock (optional enhancement):

Recursive mock translation
+    const mockTranslateObject = (obj) => {
+        const translated = {};
+        for (const [key, value] of Object.entries(obj)) {
+            if (typeof value === 'string') {
+                translated[key] = mockTranslate(value);
+            } else if (typeof value === 'object' && value !== null) {
+                translated[key] = mockTranslateObject(value);
+            } else {
+                translated[key] = value;
+            }
+        }
+        return translated;
+    };
+
     if (isString) {
         return mockTranslate(content);
     } else {
-        const translated = {};
-        for (const [key, value] of Object.entries(content)) {
-            if (typeof value === 'string') {
-                translated[key] = mockTranslate(value);
-            } else {
-                translated[key] = value;
-            }
-        }
-        return translated;
+        return mockTranslateObject(content);
     }

Comment on lines +7 to +20
// 1. Check query param ?lang=xx
let lang = req.query.lang;

// 2. Check Accept-Language header
if (!lang && req.headers['accept-language']) {
// Simple parse: take the first language code (e.g., 'en-US,en;q=0.9' -> 'en-US')
// And maybe just take the first 2 chars or the full code.
// Lingo.dev likely supports standard BCP-47.
const acceptLang = req.headers['accept-language'].split(',')[0].trim();
lang = acceptLang;
}

// 3. Default to English
req.targetLang = lang || 'en';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Normalize lang before assigning req.targetLang.

req.query.lang can be an array/object and Accept-Language can include ;q= values. Normalizing avoids unexpected locale strings downstream.

🔧 Proposed normalization
-    let lang = req.query.lang;
+    let lang = req.query.lang;
+    if (Array.isArray(lang)) lang = lang[0];
+    if (typeof lang === 'string') lang = lang.trim();
+    if (!lang) lang = undefined;

     // 2. Check Accept-Language header
     if (!lang && req.headers['accept-language']) {
-        const acceptLang = req.headers['accept-language'].split(',')[0].trim();
+        const acceptLang = req.headers['accept-language']
+            .split(',')[0]
+            .split(';')[0]
+            .trim();
         lang = acceptLang;
     }
🤖 Prompt for AI Agents
In `@community/error-localization-engine/middleware/localizer.js` around lines 7 -
20, Normalize the derived lang before assigning req.targetLang: if
req.query.lang is an array or object, coerce it to a string by taking the first
element/value; when parsing req.headers['accept-language'], split on ',' then
drop any quality suffix by splitting on ';' and trimming the result; lowercase
or otherwise normalize the token (e.g., toLowerCase()) and optionally validate
it against a simple BCP-47-ish pattern before assigning to req.targetLang;
finally fall back to 'en' if the normalized value is empty or invalid. Ensure
you update the logic around req.query.lang, acceptLang (the variable from
req.headers['accept-language']), and the final assignment to req.targetLang.

Comment on lines +40 to +90
## 🧪 Testing the API

The API detects language preference via:
1. `?lang=xx` query parameter (High priority)
2. `Accept-Language` header (Low priority)

### 1. English (Default)
**Request:**
```bash
curl -X POST http://localhost:3000/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"email": "invalid-email", "password": "123"}'
```
**Response:**
```json
{
"error": "Validation Failed",
"message": "Please provide a valid email address."
}
```

### 2. Spanish (via Query Param)
**Request:**
```bash
curl -X POST "http://localhost:3000/api/auth/signup?lang=es" \
-H "Content-Type: application/json" \
-d '{"email": "invalid-email", "password": "123"}'
```
**Response (Localized):**
```json
{
"error": "Falló la validación",
"message": "Por favor proporcione una dirección de correo electrónico válida."
}
```

### 3. French (via Header)
**Request:**
```bash
curl -X POST http://localhost:3000/api/auth/signup \
-H "Content-Type: application/json" \
-H "Accept-Language: fr" \
-d '{"email": "test@example.com", "password": "short"}'
```
**Response (Localized):**
```json
{
"error": "Échec de la validation",
"message": "Le mot de passe doit contenir au moins 6 caractères."
}
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify mock‑mode output in the API examples.

If the demo runs without LINGO_API_KEY, responses may be mock‑localized (e.g., prefixed with [es]/[fr]) rather than fully translated. A short note here would reduce confusion for first‑time testers.

📝 Suggested doc note
 The API detects language preference via:
 1. `?lang=xx` query parameter (High priority)
 2. `Accept-Language` header (Low priority)
+
+> Note: If `LINGO_API_KEY` is not set, the demo uses mock localization and responses may be prefixed with `[xx]`.
🤖 Prompt for AI Agents
In `@community/error-localization-engine/README.md` around lines 40 - 90, Add a
short clarifying note under the "🧪 Testing the API" section (before the
examples for English/Spanish/French) that explains if LINGO_API_KEY is not set
the server runs in mock mode and localized responses may be mock-prefixed (e.g.,
"[es] ..." or "[fr] ...") rather than fully translated; mention that real
translations are returned when LINGO_API_KEY is provided and that language
detection still follows the `?lang=xx` query parameter and `Accept-Language`
header priority rules already described.

Comment on lines +73 to +78
const successMsg = await localizeError({
message: "Login successful.",
token: "fake-jwt-token-123456"
}, lang);

res.json(successMsg);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Token may be incorrectly localized.

The token field is passed to localizeError, which may attempt to translate it. Non-translatable fields like tokens should be added after localization.

Suggested fix
-    const successMsg = await localizeError({ 
-        message: "Login successful.",
-        token: "fake-jwt-token-123456"
-    }, lang);
+    const successMsg = await localizeError({ 
+        message: "Login successful."
+    }, lang);
+    successMsg.token = "fake-jwt-token-123456";

     res.json(successMsg);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const successMsg = await localizeError({
message: "Login successful.",
token: "fake-jwt-token-123456"
}, lang);
res.json(successMsg);
const successMsg = await localizeError({
message: "Login successful."
}, lang);
successMsg.token = "fake-jwt-token-123456";
res.json(successMsg);
🤖 Prompt for AI Agents
In `@community/error-localization-engine/routes/auth.js` around lines 73 - 78, The
token is being passed into localizeError (see localizeError call creating
successMsg) which may try to translate it; change the flow so you first call
localizeError with only translatable fields (e.g., message) to get the localized
payload, then attach the non-translatable token field (e.g., token:
"fake-jwt-token-123456") onto the returned object before sending res.json,
ensuring localizeError is not given the token.

Comment on lines +1 to +72
const axios = require('axios');

async function runTests() {
const baseURL = 'http://127.0.0.1:3000/api/auth';

console.log('--- Starting Verification ---');

// Test 1: Signup Validation Error (Spanish)
try {
console.log('\n[Test 1] POST /signup?lang=es (Invalid Email)');
await axios.post(`${baseURL}/signup?lang=es`, {
email: 'invalid',
password: '123'
});
console.log('❌ FAIL: Expected 400 error, got success');
} catch (err) {
if (err.response) {
console.log('Response Status:', err.response.status);
console.log('Response Body:', err.response.data);
const msg = err.response.data.message || '';
if (msg.includes('[es]')) {
console.log('✅ PASS: Localized to Spanish');
} else {
console.log('❌ FAIL: Not localized correctly');
}
} else {
console.error('❌ FAIL: Network/Server Error:', err.message);
}
}

// Test 2: Signup Validation Error (French via Header)
try {
console.log('\n[Test 2] POST /signup (Header: fr) (Short Password)');
await axios.post(`${baseURL}/signup`, {
email: 'valid@email.com',
password: '123'
}, {
headers: { 'Accept-Language': 'fr' }
});
console.log('❌ FAIL: Expected 400 error, got success');
} catch (err) {
if (err.response) {
console.log('Response Status:', err.response.status);
console.log('Response Body:', err.response.data);
const msg = err.response.data.message || '';
if (msg.includes('[fr]')) {
console.log('✅ PASS: Localized to French');
} else {
console.log('❌ FAIL: Not localized correctly');
}
} else {
console.error('❌ FAIL: Network/Server Error:', err.message);
}
}

// Test 3: Success Case (English Default)
try {
console.log('\n[Test 3] POST /signup (Valid Data)');
const res = await axios.post(`${baseURL}/signup`, {
email: `user${Date.now()}@example.com`,
password: 'securepassword123'
});
console.log('Response Status:', res.status);
console.log('Response Body:', res.data);
if (res.data.message && !res.data.message.includes('[')) {
console.log('✅ PASS: English default (no mock prefix)');
} else {
console.log('❌ FAIL: Unexpected content in success message');
}
} catch (err) {
console.error('❌ FAIL: Unexpected Error:', err.response ? err.response.data : err.message);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate the verify.js file and examine its current state
find . -name "verify.js" -type f 2>/dev/null | head -20

Repository: lingodotdev/lingo.dev

Length of output: 112


🏁 Script executed:

# Check for environment variable configuration patterns in the project
find . -name ".env*" -o -name "*.config.js" -o -name "config.js" | head -20

Repository: lingodotdev/lingo.dev

Length of output: 138


🏁 Script executed:

# Look for PORT references in the codebase
rg "PORT|port" --type js --type json -B 2 -A 2 | head -100

Repository: lingodotdev/lingo.dev

Length of output: 5155


🏁 Script executed:

# Check package.json for dependencies
find . -name "package.json" -type f | head -5

Repository: lingodotdev/lingo.dev

Length of output: 266


🏁 Script executed:

# Look for LINGO_API_KEY references
rg "LINGO_API_KEY|lingo" --type js -B 2 -A 2 | head -50

Repository: lingodotdev/lingo.dev

Length of output: 3139


🏁 Script executed:

# Check the .env.example file to see what environment variables are expected
cat ./community/error-localization-engine/.env.example

Repository: lingodotdev/lingo.dev

Length of output: 106


🏁 Script executed:

# Examine the server.js file to see how the port is configured
cat -n ./community/error-localization-engine/server.js | head -50

Repository: lingodotdev/lingo.dev

Length of output: 1694


🏁 Script executed:

# Check the lingoClient.js to understand the LINGO_API_KEY behavior
cat -n ./community/error-localization-engine/lingoClient.js

Repository: lingodotdev/lingo.dev

Length of output: 2380


🏁 Script executed:

# Check the package.json in the error-localization-engine folder
cat ./community/error-localization-engine/package.json

Repository: lingodotdev/lingo.dev

Length of output: 458


🏁 Script executed:

# Check how verify.js is meant to be run (look for npm scripts or documentation)
cat ./community/error-localization-engine/package.json

Repository: lingodotdev/lingo.dev

Length of output: 458


🏁 Script executed:

# Check if there's a README or any documentation about running verify.js
find ./community/error-localization-engine -name "README*" -o -name "*.md" | xargs cat 2>/dev/null

Repository: lingodotdev/lingo.dev

Length of output: 2432


🏁 Script executed:

# Check the current verify.js file completely to see the full context
cat -n ./community/error-localization-engine/verify.js

Repository: lingodotdev/lingo.dev

Length of output: 3326


Add environment variable support for PORT and improve mock/live mode detection.

The hardcoded port 3000 bypasses the server's environment-based configuration (which respects process.env.PORT). Additionally, the localization assertions assume mock mode prefixes [es]/[fr] without detecting whether live Lingo.dev translation is enabled.

Add require('dotenv').config(), load PORT from environment, and detect mock mode by checking both whether LINGO_API_KEY is missing OR set to the placeholder value:

🛠️ Suggested update
-const axios = require('axios');
+const axios = require('axios');
+require('dotenv').config();
+
+const port = process.env.PORT || 3000;
+const baseURL = `http://127.0.0.1:${port}/api/auth`;
+axios.defaults.timeout = 5000;
+const isMockMode = !process.env.LINGO_API_KEY || process.env.LINGO_API_KEY === 'your_api_key_here';
+
+function checkLocalization(msg, lang) {
+    if (!msg) return false;
+    if (isMockMode) return msg.includes(`[${lang}]`);
+    console.log(`ℹ️ Live mode detected; skipping mock-prefix assertion for ${lang}.`);
+    return true;
+}

 async function runTests() {
-    const baseURL = 'http://127.0.0.1:3000/api/auth';
-
     console.log('--- Starting Verification ---');
@@
-            if (msg.includes('[es]')) {
+            if (checkLocalization(msg, 'es')) {
                 console.log('✅ PASS: Localized to Spanish');
             } else {
                 console.log('❌ FAIL: Not localized correctly');
             }
@@
-            if (msg.includes('[fr]')) {
+            if (checkLocalization(msg, 'fr')) {
                 console.log('✅ PASS: Localized to French');
             } else {
                 console.log('❌ FAIL: Not localized correctly');
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const axios = require('axios');
async function runTests() {
const baseURL = 'http://127.0.0.1:3000/api/auth';
console.log('--- Starting Verification ---');
// Test 1: Signup Validation Error (Spanish)
try {
console.log('\n[Test 1] POST /signup?lang=es (Invalid Email)');
await axios.post(`${baseURL}/signup?lang=es`, {
email: 'invalid',
password: '123'
});
console.log('❌ FAIL: Expected 400 error, got success');
} catch (err) {
if (err.response) {
console.log('Response Status:', err.response.status);
console.log('Response Body:', err.response.data);
const msg = err.response.data.message || '';
if (msg.includes('[es]')) {
console.log('✅ PASS: Localized to Spanish');
} else {
console.log('❌ FAIL: Not localized correctly');
}
} else {
console.error('❌ FAIL: Network/Server Error:', err.message);
}
}
// Test 2: Signup Validation Error (French via Header)
try {
console.log('\n[Test 2] POST /signup (Header: fr) (Short Password)');
await axios.post(`${baseURL}/signup`, {
email: 'valid@email.com',
password: '123'
}, {
headers: { 'Accept-Language': 'fr' }
});
console.log('❌ FAIL: Expected 400 error, got success');
} catch (err) {
if (err.response) {
console.log('Response Status:', err.response.status);
console.log('Response Body:', err.response.data);
const msg = err.response.data.message || '';
if (msg.includes('[fr]')) {
console.log('✅ PASS: Localized to French');
} else {
console.log('❌ FAIL: Not localized correctly');
}
} else {
console.error('❌ FAIL: Network/Server Error:', err.message);
}
}
// Test 3: Success Case (English Default)
try {
console.log('\n[Test 3] POST /signup (Valid Data)');
const res = await axios.post(`${baseURL}/signup`, {
email: `user${Date.now()}@example.com`,
password: 'securepassword123'
});
console.log('Response Status:', res.status);
console.log('Response Body:', res.data);
if (res.data.message && !res.data.message.includes('[')) {
console.log('✅ PASS: English default (no mock prefix)');
} else {
console.log('❌ FAIL: Unexpected content in success message');
}
} catch (err) {
console.error('❌ FAIL: Unexpected Error:', err.response ? err.response.data : err.message);
}
const axios = require('axios');
require('dotenv').config();
const port = process.env.PORT || 3000;
const baseURL = `http://127.0.0.1:${port}/api/auth`;
axios.defaults.timeout = 5000;
const isMockMode = !process.env.LINGO_API_KEY || process.env.LINGO_API_KEY === 'your_api_key_here';
function checkLocalization(msg, lang) {
if (!msg) return false;
if (isMockMode) return msg.includes(`[${lang}]`);
console.log(`ℹ️ Live mode detected; skipping mock-prefix assertion for ${lang}.`);
return true;
}
async function runTests() {
console.log('--- Starting Verification ---');
// Test 1: Signup Validation Error (Spanish)
try {
console.log('\n[Test 1] POST /signup?lang=es (Invalid Email)');
await axios.post(`${baseURL}/signup?lang=es`, {
email: 'invalid',
password: '123'
});
console.log('❌ FAIL: Expected 400 error, got success');
} catch (err) {
if (err.response) {
console.log('Response Status:', err.response.status);
console.log('Response Body:', err.response.data);
const msg = err.response.data.message || '';
if (checkLocalization(msg, 'es')) {
console.log('✅ PASS: Localized to Spanish');
} else {
console.log('❌ FAIL: Not localized correctly');
}
} else {
console.error('❌ FAIL: Network/Server Error:', err.message);
}
}
// Test 2: Signup Validation Error (French via Header)
try {
console.log('\n[Test 2] POST /signup (Header: fr) (Short Password)');
await axios.post(`${baseURL}/signup`, {
email: 'valid@email.com',
password: '123'
}, {
headers: { 'Accept-Language': 'fr' }
});
console.log('❌ FAIL: Expected 400 error, got success');
} catch (err) {
if (err.response) {
console.log('Response Status:', err.response.status);
console.log('Response Body:', err.response.data);
const msg = err.response.data.message || '';
if (checkLocalization(msg, 'fr')) {
console.log('✅ PASS: Localized to French');
} else {
console.log('❌ FAIL: Not localized correctly');
}
} else {
console.error('❌ FAIL: Network/Server Error:', err.message);
}
}
// Test 3: Success Case (English Default)
try {
console.log('\n[Test 3] POST /signup (Valid Data)');
const res = await axios.post(`${baseURL}/signup`, {
email: `user${Date.now()}@example.com`,
password: 'securepassword123'
});
console.log('Response Status:', res.status);
console.log('Response Body:', res.data);
if (res.data.message && !res.data.message.includes('[')) {
console.log('✅ PASS: English default (no mock prefix)');
} else {
console.log('❌ FAIL: Unexpected content in success message');
}
} catch (err) {
console.error('❌ FAIL: Unexpected Error:', err.response ? err.response.data : err.message);
}
}
🤖 Prompt for AI Agents
In `@community/error-localization-engine/verify.js` around lines 1 - 72, The
script currently hardcodes port 3000 and always expects mock-prefixed
localization; update runTests to require('dotenv').config(), build baseURL using
const port = process.env.PORT || 3000 and const baseURL =
`http://127.0.0.1:${port}/api/auth`, and detect mock mode via a boolean like
const isMock = !process.env.LINGO_API_KEY || process.env.LINGO_API_KEY ===
'your_lingo_api_key_here'; then adjust the localization assertions (in the POST
/signup error checks and success check) to only expect the mock prefix
'[es]'/'[fr]' when isMock is true, otherwise validate that translated messages
exist without assuming the mock prefix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build Demo Apps, Integrations etc & Win Exclusive Lingo.dev Swag!

1 participant