La versione inglese di un analizzatore Cache-Control appena rilasciato mostrava testo giapponese: il suo stato riportava “新鮮” invece di “Fresh”. L'errore risaliva a una logica condivisa che restituiva stringhe giapponesi hard-coded, mentre la pagina forniva solo etichette in inglese.

Lo sviluppatore crea una serie di strumenti leggeri per il browser, ognuno con una pagina in inglese e una in giapponese che riutilizzano le stesse funzioni di parsing e la stessa logica di base. Solo il testo visibile dovrebbe differire. Quando l'analizzatore Cache-Control è stato rilasciato, l'interfaccia inglese mostrava le etichette corrette, ma i valori renderizzati provenivano dal livello logico, che conteneva ancora letterali in giapponese. Non sono comparsi errori in console; la pagina sembrava normale, eppure le informazioni presentate agli utenti anglofoni erano errate.

Perché la logica condivisa può tradire la traduzione

Il bug derivava da una scelta di progettazione: la funzione principale che decide cosa mostrare restituiva stringhe letterali in giapponese. Il livello della pagina, responsabile del testo circostante in inglese, non ha mai avuto la possibilità di sostituire quei valori. Poiché la logica e l'interfaccia utente (UI) erano nettamente separate, il problema è rimasto invisibile durante i test: tecnicamente tutto "funzionava", anche se la lingua rivolta all'utente era errata.

L'aspetto negativo è che la lingua utilizzata all'interno del modulo condiviso diventa quella predefinita per ogni front-end che lo consuma. Se è richiesta una lingua diversa, il valore predefinito diventa un bug nascosto.

La soluzione: chiavi, pacchetti e una rete di sicurezza

L'autore ha riscritto l'architettura per separare le responsabilità:

  • I message pack ora contengono tutte le stringhe leggibili dall'uomo per ogni lingua.
  • La logica condivisa restituisce solo chiavi simboliche, mai testo grezzo.
  • Le pagine cercano la parola appropriata nel pacchetto pertinente in base alla chiave.

Quando un messaggio deve includere un numero, il nuovo codice utilizza una piccola funzione invece di una template string. Ciò consente a ogni lingua di decidere dove collocare il numero, adattandosi alle differenze nell'ordine delle parole.

È stato aggiunto anche un semplice passaggio di analisi statica: il processo di build scansiona i file condivisi alla ricerca di caratteri giapponesi. Se ne appare uno, lo sviluppatore viene avvisato immediatamente, impedendo che testo straniero hard-coded si ripresenti.

Cosa l'esperienza ha insegnato all'autore

  1. La traduzione funge da fase di revisione. Mentre scriveva i messaggi in inglese, l'autore ha notato che alcuni equivalenti giapponesi erano vaghi. Tradurre ha imposto una formulazione più chiara in entrambe le lingue.
  2. Le funzioni condivise che restituiscono stringhe bloccano una lingua per tutti. Se una funzione decide la lingua, qualsiasi consumatore che ne attenda una diversa eredita l'errore. Il bug non è un glitch dell'interfaccia utente; è un difetto logico.

Raccomandazioni per chiunque gestisca strumenti multilingue

  • Restituire chiavi, non stringhe, dalle funzioni principali. Lasciare che il livello UI gestisca la localizzazione.
  • Oppure passare le stringhe desiderate alla funzione come parametri. Questo mantiene la logica agnostica rispetto alla lingua.
  • Controllare i moduli condivisi per individuare testo in lingua nativa hard-coded. Una rapida ricerca di caratteri non ASCII può far emergere problemi nascosti.
  • Aggiungere un controllo durante la build per i caratteri stranieri nel codice condiviso. La rilevazione precoce è meglio della confusione post-rilascio.

Cosa monitorare in futuro

Conclusione: Se il tuo progetto condivide codice tra diverse versioni linguistiche, assicurati che la parte condivisa non decida mai la formulazione. Lascia che ogni pagina fornisca le proprie parole, ed eviterai l'imbarazzo di una pagina in inglese che parla accidentalmente giapponese.