הגרסה האנגלית של מנתח Cache-Control ששוחרר לאחרונה הציגה טקסט ביפנית — הסטטוס שלו הופיע כ-"新鮮" במקום "Fresh". הטעות נבעה מלוגיקה משותפת שהחזירה מחרוזות ביפנית שקודדו באופן קשיח (hard-coded), בעוד שהדף סיפק תיוגים באנגלית בלבד.

המפתח בונה סדרה של כלי דפדפן קלילים, שלכל אחד מהם דף אנגלי ודף יפני המשתמשים מחדש באותן פונקציות ניתוח (parsing) ובלוגיקת ליבה. רק הניסוח הגלוי אמור להיות שונה. כאשר מנתח ה-Cache-Control שוחרר, הממשק האנגלי הציג את התיוגים הנכונים, אך הערכים שהוצגו הגיעו משכבת הלוגיקה, שעדיין הכילה ליטרלים (literals) ביפנית. לא הופיעו שגיאות בקונסול; הדף נראה תקין, אך המידע שהוצג למשתמשים דוברי אנגלית היה שגוי.

למה לוגיקה משותפת עלולה לבגוד בתרגום

הבאג נבע מבחירה בעיצוב: פונקציית הליבה שקובעת מה להציג החזירה מחרוזות ליטרליות ביפנית. שכבת הדף, האחראית על הטקסט האנגלי שמסביב, לא קיבלה מעולם הזדמנות להחליף את הערכים הללו. מכיוון שהלוגיקה וה-UI היו מופרדים בצורה נקייה, הבעיה נותרה בלתי נראית במהלך הבדיקות — מבחינה טכנית הכל "עבד", למרות שהשפה המוצגת למשתמש הייתה שגויה.

החיסרון הוא שהשפה המשמשת בתוך המודול המשותף הופכת לברירת המחדל עבור כל front-end שצורך אותו. אם נדרשת שפה אחרת, ברירת המחדל הופכת לבאג נסתר.

הפתרון: מפתחות, חבילות ורשת ביטחון

המחבר כתב מחדש את הארכיטקטורה כדי להפריד בין תחומי אחריות:

  • Message packs (חבילות הודעות) מחזיקות כעת את כל המחרוזות הניתנות לקריאה אנושית עבור כל שפה.
  • Shared logic (לוגיקה משותפת) מחזירה רק מפתחות סימבוליים, לעולם לא טקסט גולמי.
  • Pages (דפים) מחפשים את המילה המתאימה מהחבילה הרלוונטית על בסיס המפתח.

כאשר הודעה חייבת לכלול מספר, הקוד החדש משתמש בפונקציה קטנה במקום ב-template string. זה מאפשר לכל שפה להחליט היכן המספר צריך להופיע, תוך התחשבות בהבדלים בסדר המילים.

נוסף גם שלב פשוט של ניתוח סטטי (static-analysis): תהליך ה-build סורק קבצים משותפים לאיתור תווים יפניים. אם מופיעים תווים כאלה, המפתח מקבל התראה מיידית, מה שמונע מטקסט זר שקודד באופן קשיח לחזור פנימה.

מה הניסיון לימד את המחבר

  1. תרגום משמש כשלב של בקרה. בזמן כתיבת הודעות באנגלית, המחבר הבחין כי כמה מקבילות ביפנית היו מעורפלות. התרגום אילץ ניסוח ברור יותר בשתי השפות.
  2. פונקציות משותפות המחזירות מחרוזות קובעות שפה עבור כולם. אם פונקציה קובעת את השפה, כל צרכן שמצפה לשפה אחרת יורש את הטעות. הבאג אינו תקלה ב-UI; מדובר בפגם לוגי.

המלצות לכל מי שמחזיק בכלים רב-לשוניים

  • החזירו מפתחות, לא מחרוזות, מפונקציות ליבה. תנו לשכבת ה-UI לטפל ב-localization (לוקליזציה).
  • או העבירו את המחרוזות הרצויות לפונקציה כפרמטרים. זה שומר על הלוגיקה אגנוסטית (agnostic) לשפה.
  • בצעו ביקורת (Audit) למודולים משותפים לאיתור טקסט בשפת אם שקודד באופן קשיח. חיפוש מהיר אחר תווים שאינם ASCII יכול לחשוף בעיות נסתרות.
  • הוסיפו בדיקה בזמן ה-build לאיתור תווים זרים בקוד המשותף. זיהוי מוקדם עדיף על בלבול לאחר השחרור.

מה לשים לב אליו בהמשך

שורה תחתונה: אם הפרויקט שלכם משתף קוד בין גרסאות שפה שונות, ודאו שהחלק המשותף לעולם לא יקבע את הניסוח. תנו לכל דף לספק את המילים שלו, וכך תמנעו את המבוכה של דף באנגלית שמדבר בטעות יפנית.