Consulting Work Ιστολόγιο Επικοινωνία
← Πίσω στο ιστολόγιο

Η εντολή που έσβησε τις λάθος είκοσι έξι γλώσσες

Η εντολή που έσβησε τις λάθος είκοσι έξι γλώσσες

Είπα στην αυτοματοποίηση του δικού μου site να περιορίσει το blog σε τέσσερις γλώσσες. Δύο μέρες αργότερα ανακάλυψα ότι είχε σβήσει σιωπηλά είκοσι έξι γλώσσες και από την αρχική σελίδα, χωρίς να το αντιληφθεί ούτε εγώ ούτε κανένας επισκέπτης.

TL;DR

  • Μια εντολή που αφορούσε το blog εφαρμόστηκε σε ολόκληρο το site.
  • 26 από τις 30 γλώσσες εξαφανίστηκαν από την αρχική σελίδα, τη σελίδα βιογραφικού και κάθε κείμενο πλοήγησης.
  • Τίποτα δεν κατέρρευσε, καμία σελίδα δεν έβγαλε 404, οπότε κανείς δεν το πρόσεξε για δύο μέρες.
  • Η λύση βρέθηκε στο ιστορικό του git, όχι στη μνήμη μου για το πώς έμοιαζε παλιότερα το site.
  • Το πραγματικό μάθημα: πριν τρέξει οποιαδήποτε αυτοματοποιημένη αλλαγή, ζήτα τη λίστα με τα ακριβή αρχεία που θα αγγίξει, και διάβασέ τη πριν διαγραφεί οτιδήποτε.

Γιατί ήθελα λιγότερες γλώσσες εξαρχής

Το site μου είχε φτάσει τις τριάντα γλώσσες μέσα σε λίγους μήνες: αρχική σελίδα, βιογραφικό και ένα blog που ανανεώνω σχεδόν κάθε λίγες μέρες. Είχα ήδη γράψει παλιότερα πόσο επικίνδυνο είναι αυτό: η αυτόματη μετάφραση είναι αρκετά άπταιστη ώστε να φαίνεται σωστή, αλλά αρκετά λανθασμένη ώστε να σε ρεζιλέψει, σε μια γλώσσα που εσύ προσωπικά δεν μπορείς να ελέγξεις. Η αρχική σελίδα και το βιογραφικό αλλάζουν ελάχιστα, οπότε εκεί μπορούσα να ζήσω με αυτόν τον κίνδυνο. Το blog ήταν άλλη υπόθεση. Βγαίνουν συχνά νέα άρθρα, και ειλικρινά δεν μπορώ να εγγυηθώ την ποιότητα της μετάφρασης ενός φρέσκου άρθρου στα εσθονικά την ίδια μέρα που δημοσιεύεται.

Αποφάσισα λοιπόν να περιορίσω τις γλώσσες στις οποίες μεταφράζεται το blog στις τέσσερις που πραγματικά εμπιστεύομαι τον εαυτό μου να ελέγξει: αγγλικά, ρωσικά, γερμανικά, τσεχικά. Όλες οι υπόλοιπες μένουν εκτός blog μέχρι να βρω έναν καλύτερο τρόπο επαλήθευσης. Αυτό το κομμάτι του σχεδίου ήταν σωστό. Αυτό που πήγε στραβά ήταν ο τρόπος που το ζήτησα.

Μία πρόταση, λάθος πεδίο εφαρμογής

Έδωσα μία και μοναδική εντολή: κράτα το blog σε τέσσερις γλώσσες. Σύντομη, συγκεκριμένη, τουλάχιστον έτσι νόμιζα. Αυτό που έτρεξε στην πράξη άγγιξε τρία διαφορετικά πράγματα ταυτόχρονα. Περιόρισε σωστά τους φακέλους περιεχομένου του blog στις τέσσερις γλώσσες που ήθελα. Παράλληλα όμως ξανάγραψε τη βασική λίστα γλωσσών του site, το αρχείο ρυθμίσεων που ορίζει ποιες γλώσσες υπάρχουν συνολικά, και διέγραψε το περιεχόμενο της αρχικής σελίδας και τα κείμενα πλοήγησης για τις υπόλοιπες είκοσι έξι.

Το πρόβλημα είναι ότι «το blog» και «η λίστα γλωσσών ολόκληρου του site» ζουν στο ίδιο αρχείο ρυθμίσεων. Τίποτα σε αυτό το αρχείο δεν ξεχωρίζει ποιες γλώσσες υποστηρίζει το blog από ποιες υποστηρίζει το site ως σύνολο. Αν αφαιρέσεις μια γλώσσα από αυτή τη λίστα, κάθε ενότητα που τη διαβάζει, αρχική σελίδα συμπεριλαμβανομένης, τη χάνει με μία κίνηση. Η εντολή μου όριζε μία ενότητα. Η αλλαγή που έτρεξε στην πράξη είχε πεδίο εφαρμογής το σύνολο.

Και εδώ είναι το σημείο που το έκανε επικίνδυνο και όχι απλώς λανθασμένο: τίποτα δεν χάλασε με θόρυβο. Καμία αναφορά σφάλματος, κανένα 404, καμία αποτυχία στο build. Το site απλώς σταμάτησε αθόρυβα να δημιουργεί σελίδες αρχικής και βιογραφικού για είκοσι έξι γλώσσες, και ο επιλογέας γλώσσας έπαψε να τις προσφέρει. Ένας επισκέπτης που διάβαζε το site στα πορτογαλικά κατέληγε τώρα σιωπηλά στα αγγλικά. Το «λείπει επειδή διαγράφηκε» μοιάζει ακριβώς με το «δεν υπήρξε ποτέ», και κανένα από τα δύο δεν βγάζει σφάλμα.

Πέρασαν δύο μέρες μέχρι να το προσέξω, και μόνο τυχαία, στη μέση μιας άσχετης διόρθωσης, όταν ένας σύνδεσμος «Blog» στην πλοήγηση οδηγούσε κάπου παράξενα για μία από τις γλώσσες που νόμιζα ότι ήταν ακόμα ενεργή. Αυτός ο ένας κρεμασμένος σύνδεσμος ήταν το μόνο ορατό νήμα που οδηγούσε πίσω σε ολόκληρο το πρόβλημα.

Τι έδειξε στην πραγματικότητα το diff

Το πραγματικό λάθος εδώ δεν είναι το λάθος στο πεδίο εφαρμογής καθαυτό. Είναι ότι ποτέ δεν έλεγξα τη λίστα των αρχείων που θα άγγιζε πραγματικά η αλλαγή προτού την αφήσω να τρέξει. Διάβασα μια περιγραφή μιας γραμμής για το τι υποτίθεται ότι θα έκανε, και υπέθεσα πως αυτό περιέγραφε το τι πραγματικά έκανε. Δεν ήταν έτσι.

Η διόρθωση ξεκίνησε με μία ερώτηση: τι άλλαξε, και πού. Συνέκρινα το live site με το τελευταίο commit πριν την εντολή «περιόρισε το blog», και η απάντηση ήταν άμεση και ξεκάθαρη: το βασικό αρχείο ρυθμίσεων γλωσσών, ο φάκελος περιεχομένου της αρχικής σελίδας, και είκοσι έξι αρχεία κειμένων ανά γλώσσα, κανένα από τα οποία βρισκόταν κοντά στον φάκελο του blog. Το git είχε όλα αυτά τα αρχεία ακριβώς όπως ήταν πριν. Στην πραγματικότητα δεν χάθηκε τίποτα, απλώς αντικαταστάθηκε στο deploy.

Αποκατέστησα την αρχική σελίδα, το βιογραφικό και τα κείμενα πλοήγησης για όλες τις τριάντα γλώσσες από εκείνο το ιστορικό, και άφησα τον φάκελο του blog ακριβώς όπως τον είχα περιορίσει: τέσσερις γλώσσες, σκόπιμα. Έμεινε μία εκκρεμότητα. Ο σύνδεσμος «Blog» στην πλοήγηση, για κάθε αποκατεστημένη γλώσσα, οδηγούσε παλιότερα σε μια έκδοση του blog σε αυτή τη γλώσσα που πλέον δεν υπάρχει. Δεν άξιζε τον κόπο να διπλασιάσω τέσσερα άρθρα σε είκοσι έξι ακόμα γλώσσες μόνο για να καλύψω αυτόν τον έναν σύνδεσμο, οπότε ρύθμισα το template ώστε να ανακατευθύνει στο αγγλικό blog, και το άφησα έτσι.

Μία εντολή, λάθος πεδίο εφαρμογής: οι γλώσσες αρχικής σελίδας/βιογραφικού συρρικνώθηκαν σε τέσσερις και επέστρεψαν στις τριάντα δύο μέρες αργότερα, ενώ το blog παρέμεινε στις τέσσερις γλώσσες που πραγματικά είχαν προβλεφθεί

Τι θα έλεγχα διαφορετικά την επόμενη φορά

Πλέον, πριν αφήσω οποιαδήποτε αυτοματοποιημένη αλλαγή να αγγίξει ένα live site με πολλές ενότητες, κάνω μία επιπλέον ερώτηση φωναχτά: πες μου ακριβώς ποια αρχεία θα αγγίξει αυτό, όχι το feature που υποτίθεται ότι διορθώνει. Αν η απάντηση είναι ασαφής, αυτό είναι το σήμα να σταματήσω και να ελέγξω, όχι να το τρέξω και να δω τι θα γίνει. Και πριν διαγραφεί οτιδήποτε, θέλω μπροστά μου την πραγματική λίστα αρχείων, όχι μια περίληψη μιας γραμμής για το τι υποτίθεται ότι σήμαινε η εντολή. Μια λέξη πεδίου εφαρμογής μέσα σε μια εντολή, «το blog», «αυτή η ομάδα», «μόνο το frontend», δεν είναι αυτόματα το ίδιο με το πεδίο εφαρμογής της αλλαγής που ενεργοποιεί αυτή η εντολή, και τα δύο ταιριάζουν μόνο αν κάτι έχει πραγματικά ελέγξει ότι ταιριάζουν: που είναι ακριβώς η ερώτηση που θα σου έκανα πίσω. Ποια είναι η μικρότερη, πιο σίγουρα οριοθετημένη εντολή που έδωσες τελευταία και που δεν ελέγχθηκε ποτέ σε σχέση με το τι πραγματικά άγγιξε;

Need something like this for your own business? See how I can help →