De Engelse versie van een onlangs uitgebrachte Cache-Control-analyzer toonde Japanse tekst—de status gaf “新鮮” weer in plaats van “Fresh”. De fout bleek te komen door gedeelde logica die hardgecodeerde Japanse strings retourneerde, terwijl de pagina alleen Engelse labels leverde.

De ontwikkelaar bouwt een reeks lichtgewicht browsertools, elk met een Engelse en een Japanse pagina die dezelfde parsing-functies en kernlogica hergebruiken. Alleen de zichtbare bewoording zou moeten verschillen. Toen de Cache-Control-analyzer werd uitgebracht, toonde de Engelse interface de juiste labels, maar de waarden die werden weergegeven kwamen uit de logische laag, die nog steeds Japanse literals bevatte. Er verschenen geen foutmeldingen in de console; de pagina zag er normaal uit, maar de informatie die aan Engelstalige gebruikers werd gepresenteerd, was onjuist.

Waarom gedeelde logica de vertaling kan verraden

De bug ontstond door een ontwerpkeuze: de kernfunctie die bepaalt wat er getoond wordt, retourneerde letterlijke strings in het Japans. De paginalaag, die verantwoordelijk is voor de omliggende Engelse tekst, kreeg nooit de kans om die waarden te vervangen. Omdat de logica en de UI strikt gescheiden waren, bleef het probleem onzichtbaar tijdens het testen—technisch gezien "werkte" alles, ook al was de taal die de gebruiker zag onjuist.

Het nadeel is dat de taal die binnen de gedeelde module wordt gebruikt, de standaard wordt voor elke front-end die deze gebruikt. Als er een andere taal nodig is, wordt de standaardinstelling een verborgen bug.

De oplossing: keys, packs en een vangnet

De auteur schreef de architectuur opnieuw om de verantwoordelijkheden te scheiden:

  • Message packs bevatten nu alle leesbare tekst voor elke taal.
  • Gedeelde logica retourneert alleen symbolische keys, nooit ruwe tekst.
  • Pagina's zoeken het juiste woord op in het relevante pack op basis van de key.

Wanneer een bericht een getal moet bevatten, gebruikt de nieuwe code een kleine functie in plaats van een template string. Hierdoor kan elke taal zelf bepalen waar het getal hoort, wat rekening houdt met verschillen in woordvolgorde.

Er is ook een eenvoudige stap voor statische analyse toegevoegd: het build-proces scant gedeelde bestanden op Japanse tekens. Als er tekens worden gevonden, krijgt de ontwikkelaar direct een melding, zodat hardgecodeerde vreemde tekst niet opnieuw kan binnensluipen.

Wat de ervaring de auteur heeft geleerd

  1. Vertaling fungeert als een controle. Tijdens het schrijven van Engelse berichten merkte de auteur op dat sommige Japanse equivalenten vaag waren. Vertalen dwong tot een duidelijkere formulering in beide talen.
  2. Gedeelde functies die strings retourneren, leggen de taal vast voor iedereen. Als een functie de taal bepaalt, erft elke gebruiker die een andere taal verwacht de fout. De bug is geen UI-foutje; het is een logische fout.

Aanbevelingen voor iedereen die meertalige tools onderhoudt

  • Retourneer keys in plaats van strings vanuit kernfuncties. Laat de UI-laag de lokalisatie afhandelen.
  • Of geef de gewenste strings als parameters mee aan de functie. Dit houdt de logica taalonafhankelijk.
  • Controleer gedeelde modules op hardgecodeerde tekst in de moedertaal. Een snelle zoekopdracht naar niet-ASCII-tekens kan verborgen problemen aan het licht brengen.
  • Voeg een controle tijdens het build-proces toe voor vreemde tekens in gedeelde code. Vroege detectie is beter dan verwarring na de release.

Waar je voortaan op moet letten

Conclusie: Als je project code deelt tussen verschillende taalversies, zorg er dan voor dat het gedeelde deel nooit de bewoording bepaalt. Laat elke pagina zijn eigen woorden leveren, dan voorkom je de gênante situatie van een Engelse pagina die per ongeluk Japans spreekt.