Upgrade auf Symfony 8, Nutzerregistrierung lokal: Das Formular besteht die Validierung, die Anfrage läuft ordentlich los, und — 500. Im Log ein Validierungsfehler für eine URL, die einen Moment zuvor durchgegangen ist. In der Produktion nichts davon. Das perfekte Rezept für eine Stunde Starren auf den falschen Teil des Codes.
Was sich in Symfony 8 geändert hat
Die Constraint Assert\Url verlangt nun standardmäßig eine Top-Level-Domain: beispiel.de geht durch, localhost nicht, ebenso wenig jeder Host ohne Punkt. Die Option requireTld gab es auch vorher, aber mit umgekehrtem Standard. Die Änderung ist für die Produktion vernünftig — kaum eine echte Adresse hat einen Host ohne Domain — und vollkommen unsichtbar, bis man lokal etwas unter einer Adresse wie http://localhost:5173 startet.
Warum die Validierung durchging und die Anwendung abstürzte
Die erste Regel saß auf dem eingehenden Anfrageobjekt: dem Feld für die Rücksprungadresse, das das Frontend sendet. Dort haben wir requireTld sofort abgeschaltet, und das Formular ging durch. Doch die Anwendung validierte dieselbe Adresse ein zweites Mal, weiter unten — im Service, der den Link für die Aktivierungsmail zusammenbaut, mit eigenem Assert\Url-Aufruf und Standardeinstellungen. Die erste Prüfung besteht, die zweite wirft mitten im Mailversand, und statt einer freundlichen Meldung bekommt der Nutzer einen 500.
Die Korrektur und die eigentliche Lehre
Die technische Korrektur ist trivial: requireTld: false an beiden Stellen. Die eigentliche Lehre ist, dass dieselbe Validierungsregel nicht an zwei Stellen mit zwei Konfigurationen leben darf. Validierung gehört an die Systemgrenze, dorthin, wo die Daten hereinkommen; tief in einem Service sollte es keine Überraschungen über die Form von Daten geben, die den Eingang bereits passiert haben. Die zweite Prüfung haben wir nicht korrigiert, sondern entfernt.
Was beim Umstieg noch bricht
Derselbe Umstieg hat auch die Methode add() der Konsolenanwendung zugunsten von addCommand() entfernt — eine Kleinigkeit, die jede manuelle Befehlsregistrierung bricht. Beide Änderungen haben etwas gemeinsam: Sie sind dokumentiert, sinnvoll, und man bemerkt sie erst, wenn etwas umfällt. Vor einem Major-Upgrade lohnt es sich, das Changelog mit der Frage durchzugehen: „Wo verlässt sich mein Code stillschweigend auf diesen Standard?”
Ein Fehler, der nur lokal auftritt, ist nicht weniger ernst — nur geduldiger.