2 Punkte von GN⁺ 2024-02-17 | 2 Kommentare | Auf WhatsApp teilen
  • Selbst wenn eine tatsächliche Funktion wegen einer bestimmten Plattform oder eines eingestellten Zustands nicht bereitgestellt werden kann, muss ein „Nichtstun“-Verhalten innerhalb des dokumentierten API-Vertrags entworfen werden, damit bestehende Apps nicht kaputtgehen
  • In einer Umgebung ohne Druckinfrastruktur wie Xbox ist für nach PC-Maßstäben geschriebene Apps eine erfolgreiche Antwort mit 0 Druckern sicherer als eine NotSupportedException
  • Dieser Ansatz ist eine inert API: API-Oberfläche und Spezifikation bleiben erhalten, aber tatsächlich wird keine nützliche Arbeit ausgeführt
  • Wenn in einer eingestellten Widget-API CreateWidget erfolgreich ist, aber nullptr zurückgibt, geraten Aufrufer in einen widersprüchlichen Zustand; der dokumentierte Fehlerpfad mit ERROR_CANCELLED ist konsistenter
  • Eine korrekt gestaltete inert API lässt nur die Funktionalität verschwinden und reduziert über bereits im bestehenden Code berücksichtigte Fehlerpfade Ausnahmen, ungültige Handles und Abstürze

Auch ohne Funktion bleibt der API-Vertrag bestehen

  • Es gibt Fälle, in denen eine API nichts tun soll, aber auch dieses Nichtstun muss zum bestehenden Code und zum dokumentierten Verhalten passen
  • Falsch entworfenes Nichtstun kann Ausnahmen, widersprüchliche Rückgabewerte und ungültige Zustände erzeugen und so zu App-Abstürzen oder unnötigen Benutzerfehlern führen

So werden Druck-APIs auf Xbox inert gemacht

  • Windows verfügt über eine umfangreiche Druckinfrastruktur, Xbox jedoch nicht
  • Wenn eine App auf Xbox zu drucken versucht und die Druckfunktion dabei eine NotSupportedException auslöst, kann das größere Probleme verursachen
    • Apps, die auf Xbox installiert sind, wurden wahrscheinlich vor allem auf PCs getestet
    • Auf dem PC ist Drucken immer möglich, daher kann eine unbehandelte Ausnahme zum Absturz der App führen
    • Selbst wenn die Ausnahme abgefangen wird, könnte der Benutzer eine Fehlermeldung wie „Geben Sie dem Support den Incident-Code an“ sehen
  • Ein besseres Design ist, dass die Druckfunktion erfolgreich ist, aber meldet, dass keine installierten Drucker vorhanden sind
    • Die App zeigt dann eine UI zur Druckerauswahl und eine leere Liste an
    • Der Benutzer sieht, dass keine Drucker vorhanden sind, und kann den Druckvorgang abbrechen
  • Für Apps, die bei der Druckerinstallation helfen wollen, kann die Installationsfunktion sofort zurückkehren und einen Ergebniscode liefern, der bedeutet, dass der Benutzer den Vorgang abgebrochen hat

Bedingungen für eine inert API

  • Ein solches „Nichts tun“-Verhalten wird als inert bezeichnet
  • Eine inert API behält die API-Oberfläche bei und verhält sich gemäß der Spezifikation, führt aber tatsächlich keine nützliche Arbeit aus
  • Entscheidend ist, auf eine Weise nichts zu tun, die mit der Dokumentation konsistent ist und bestehendem Code mit der geringsten Wahrscheinlichkeit Probleme bereitet
  • Für die Druck-API könnte man zusätzlich eine Funktion einführen, die prüft, ob Drucken überhaupt möglich ist
    • Apps könnten diese Funktion nutzen, um den Button „Drucken“ auf Systemen auszublenden, die Drucken überhaupt nicht unterstützen
    • Apps, die einfach davon ausgehen, dass Drucken möglich ist, verhalten sich dann so, als liefen sie auf einem System „ohne Drucker und ohne wirksamen Installationsversuch“

Welches Design man bei einer auslaufenden Widget-API vermeiden sollte

  • Die auslaufende API enthält eine Funktion zum Erzeugen eines Widget-Handles, eine Funktion, die ein Widget-Handle entgegennimmt, und eine Funktion zum Schließen eines Widget-Handles
  • Der ursprüngliche Vorschlag war, dass CreateWidget S_OK zurückgibt und dabei *widget = nullptr setzt
    • Der Aufruf war erfolgreich, aber es wurde kein gültiges Handle geliefert
    • In tatsächlichem Testcode gab es Fälle, in denen der Erfolg nicht am Rückgabewert, sondern daran erkannt wurde, ob das Handle null war
  • Auch ein Design, bei dem EnableWidget „ungültiges Handle“ zurückgibt, verwirrt Aufrufer
    • Die App übergibt das nach erfolgreichem CreateWidget erhaltene Handle an EnableWidget
    • Die API antwortet, dass dieses Handle ungültig sei
    • Der Aufrufer erlebt damit einen widersprüchlichen Zustand: „Ich habe ein Widget angefordert und erhalten, aber wenn ich es jetzt erneut verwende, heißt es plötzlich, es sei gar kein Widget“

Überarbeitung mit einem dokumentierten Fehlerpfad

  • In der bestehenden Dokumentation gibt es bereits den Rückgabewert ERROR_CANCELLED, der bedeutet, dass der Benutzer die Widget-Erstellung abgebrochen hat
  • Da Apps ohnehin damit umgehen müssen, dass ein Widget wegen externer Bedingungen möglicherweise nicht erstellt werden kann, kann man die Widget-Erstellung so gestalten, dass sie immer mit Benutzerabbruch fehlschlägt
  • Der Ablauf des überarbeiteten Designs ist einfach
    • CreateWidget belässt *widget = nullptr und gibt HRESULT_FROM_WIN32(ERROR_CANCELLED) zurück
    • Da die Widget-Erstellung immer fehlschlägt, gibt es kein gültiges Widget-Handle
    • GetWidgetAliases, EnableWidget, Close geben E_HANDLE zurück, also dass das Handle ungültig ist
  • Bei diesem Ansatz muss auch kein Dummy-Alias erzeugt werden
    • Da es kein gültiges Widget gibt, kann die App auch in keinem normalen Fall erfolgreich einen Alias anfordern

Maßstäbe beim Übertragen von Desktop-APIs in andere Umgebungen

  • Auf dem Desktop war die Druck-API immer vorhanden, und die Funktion zum „Abrufen der Druckerliste“ ist so dokumentiert, dass sie keine Ausnahme auslöst
  • Wenn diese API auf Xbox gebracht wird und bestehende Desktop-Apps weiterlaufen sollen, ist ein inert Verhalten korrekt, das ehrlich zurückgibt: „Auf Xbox gibt es keine Drucker“
  • Auf die Frage „Wie viele Drucker gibt es?“ mit einer Ausnahme zu reagieren, passt nicht zum dokumentierten API-Vertrag
  • Dasselbe Prinzip gilt auch beim Einstellen bestehender APIs
    • Auch wenn keine nützliche Arbeit mehr ausgeführt wird, muss das API-Verhalten mit dem Vertrag konsistent bleiben
    • Wichtig ist, Rückgabewerte und Zustände zu verwenden, die bestehender Code bereits verarbeiten kann

2 Kommentare

 
GN⁺ 2024-02-17
Lobste.rs-Kommentare
  • Gemeint ist hier, dass die Druckfunktionen sich konsistent so verhalten, als würde Drucken vollständig unterstützt, obwohl es seltsamerweise tatsächlich niemals einen Drucker zum Drucken geben wird, und das erklärt dann vieles
    Spaß beiseite: Ich stimme dieser übermäßig defensiven Programmierung und User Experience nicht zu. So erfüllt die Software stillschweigend ihre Aufgabe nicht, ohne dass man den Grund kennt, und es gibt keine Möglichkeit herauszufinden, warum. Die App sollte Fehler abfangen und, wenn möglich, eine benutzerfreundliche Meldung erzeugen, oder andernfalls zumindest die ursprüngliche Fehlermeldung dem Nutzer anzeigen. Bei Hintergrundaufgaben sollte es ein Fehlerprotokoll geben
    Ich räume ein, dass dieser Text aus der Perspektive eines API-Entwicklers und nicht eines App-Entwicklers geschrieben wurde. Daher sollte man API-Fehler dokumentieren und Fehlermeldungen bereitstellen, anhand derer die aufrufende Seite Maßnahmen ergreifen kann
    Ich mag es auch nicht, wenn in der UI Buttons versteckt werden, nur weil Zugriffsrechte fehlen. Wenn der Platz es zulässt, ist es besser, den Button anzuzeigen, aber zu deaktivieren, und beim Darüberfahren mit der Maus eine Meldung einzublenden, wie man ihn aktivieren kann
    • Man sollte auch berücksichtigen, dass dieser Text nicht aus der Perspektive eines gewöhnlichen API-Entwicklers geschrieben ist, sondern aus der eines Windows-API-Entwicklers. Microsoft vertritt seit Langem die Haltung, dass die Windows API auch bei Versionswechseln die Kompatibilität nicht brechen darf
    • Das ist eine typische Diskussion über das Postelsche Gesetz / Robustheitsprinzip. Inzwischen weiß jeder, dass das Robustheitsprinzip veraltet ist und Monster hervorgebracht hat wie HTML oder riesige Protokolle und Dateiformate, für die es schwer ist, vernünftige Parser zu schreiben
      Insgesamt ist es besser, auf Korrektheit zu bestehen. Wenn man allerdings eine bestehende Nutzerbasis von 1 Milliarde Menschen hat, ist es sehr klug, möglichst nichts kaputtzumachen, und aus Nutzersicht entsteht dadurch auch ein realer Wert auf Systemebene, weil es einfach funktioniert. Letztlich sollte die Haltung sein: früh scheitern, aber nicht dafür sorgen, dass massenhaft Dinge scheitern
    • In diesem Fall hat eine der bestehenden APIs wahrscheinlich keinen dokumentierten Fehler, weshalb es gut sein kann, dass ursprünglich gar keine Fehlerbehandlung vorgesehen war. Wenn man nicht die gesamte Bestandssoftware kaputtmachen will, muss man wohlwollend lügen
      Das hat weniger mit der API als mit ABI-Stabilität zu tun. Unter Windows sollte möglichst auch Software, die vor 15 Jahren gebaut wurde, auf neuen Betriebssystemen weiterlaufen. Man kann die Funktionssignatur nicht ändern, also muss man wohlwollend lügen, damit auch APIs, die eigentlich keine Bedeutung mehr haben, weiter funktionieren
      Zum Beispiel tut die API noch immer so, als gäbe es Active Desktop. Die Alternative wäre, in großem Umfang alte Bestandssoftware zu beschädigen
    • Dem stimme ich wirklich zu. Es gibt kaum etwas Frustrierenderes, als nach einem Button zu suchen, der auf meinem Bildschirm aus irgendeinem Grund nicht sichtbar ist, den aber jemand neben mir erklärt oder der in einem Tutorial zu sehen ist
      Dann weiß man nicht, ob die Funktion verschwunden ist oder inzwischen unter einem anderen Bildschirm vergraben wurde
    • Es stimmt, dass die App Fehler abfangen und dem Nutzer anzeigen sollte.
      Aber wenn die App das nicht tut, geben die Menschen, die diese App benutzen, Windows die Schuld. Sie geben Windows die Schuld und nicht der App, und das gilt sogar dann, wenn die App abstürzt
      Deshalb baut Microsoft Umgehungslösungen. Es ist viel einfacher, den Druckauftrag einfach verschwinden zu lassen, und dann denkt der Nutzer kurz nach und akzeptiert: „Ach ja, ich habe ja keinen Drucker.“
  • Wenn eine Funktion zur Druckerinstallation sofort zurückkehren und als Ergebniscode Der Benutzer hat den Vorgang abgebrochen liefern kann, führt das aus Sicht des Anwendungssupports mit ziemlicher Sicherheit zu unerwünschtem Verhalten, das bei der Fehlerbehandlung der Druck-API deutlich schwerer handhabbar ist, als wenn die API von Anfang an eine Ausnahme werfen würde
  • Ich nutze in letzter Zeit viel KI-gestützte Programmierung und sehe oft, dass Agenten if-Prüfungen auf null einbauen. Jedes Mal muss ich an diesen Artikel denken
    Deshalb habe ich dem Agenten gesagt, er solle solche null-Prüfungen nicht wiederholen, sondern harmlose Funktionen verwenden und beim Deklarieren einmal sicherstellen, dass der Wert niemals null ist
 
GN⁺ 2024-02-17
Hacker-News-Meinungen
  • Ich habe es als Fehler verschlucken kennengelernt und halte es für eine schlechte Praxis.
    Es löst nicht nur das eigentliche Problem nicht, dass auf der Xbox nicht gedruckt werden kann, sondern verbirgt auch, wie kaputt die Software ist, und macht das Finden von Bugs und das Testen deutlich schwieriger.
    Gos panic ist gut, weil es nicht dafür gedacht ist, zur Laufzeit missbraucht oder abgefangen zu werden, sondern beim Testen laut Alarm schlägt, dass der Programmierer etwas falsch gemacht hat.
    Wenn Akteure in einem System ihre eigenen Defekte oder Fehler aktiv verbergen, wird es exponentiell schwieriger, die Ursache zu finden und zu beheben.

    • Fehlerdesign hängt vom Kontext ab.
      In den B2B-, Microservice- und API-zentrierten Systemen, mit denen ich zu tun habe, ist es richtig, Anfragen außerhalb der Spezifikation schnell fehlschlagen zu lassen.
      Windows hat sich jedoch für Kompatibilität enorm verbogen, und es gab Fälle, in denen berühmte kaputte Software wie SimCity sogar mit Memory-Patches am Leben gehalten wurde: https://arstechnica.com/gadgets/2022/10/windows-95-went-the-...
      In einer Desktop-Umgebung, in der Nutzer den Systemcode nicht reparieren können, ist in vielen Fällen die Endnutzererfahrung wichtiger als Korrektheit.
      Warum es zu einem BSOD kam, ist nicht wichtig; Microsoft hat gelernt, dass schlechte Software oder Hardware dem Ruf von Microsoft schadet.
      Persönlich bevorzuge ich Designs, die bei ungültigen Eingaben oder Bedingungen schnell fehlschlagen oder abbrechen, aber in diesem Umfeld verstehe ich auch den Wert dieses Ansatzes.
      Entscheidend ist der Kontext, nicht die dogmatische Anwendung der einen oder anderen Seite.
      Zum Beispiel sollte man Chens Ansatz nicht auf das Design von Kernreaktoren oder High-Frequency-Trading übertragen; für eine Game-Engine kann er ausgezeichnet sein.
    • Beim Entwurf einer alternativen Runtime für eine neue Plattform ist entscheidend, selbst festzulegen, was als Fehler gilt.
      Die Frage, ob man eine Runtime-Komponente „harmlos inaktiv“ lässt, ist eine Designentscheidung, die der Frage vorausgeht, ob die Implementierung ein panic auslöst oder nicht.
      In diesem Fall ist es Microsofts Sache, die Bedeutung von „auf der Xbox drucken“ festzulegen.
      Man kann es als Fehler definieren oder theoretisch als eine Funktion, die später unterstützt werden könnte, für die es derzeit aber keine praktische Ausführungsmöglichkeit gibt.
      Wenn man einen USB-Drucker anschließt und ein „Spiel“, etwa ein Gameboy-Spiel mit Erweiterungsport, das den GB Printer unterstützte, weiß, wie gedruckt wird, könnte man theoretisch auch auf der Xbox drucken.
      Dass ein Xbox-Spiel versucht zu drucken, ist nicht zwangsläufig ein inhärenter Fehler; es als Fehler zu definieren, ist ebenfalls nur eine Entscheidung mit Trade-offs, etwa bei der Portabilität von Anwendungen.
      Man könnte wie auf der Xbox einen Auswahldialog ohne auswählbaren Drucker anzeigen, die API lügen lassen, dass gedruckt wurde, oder echtes Drucken unterstützen.
      Erst nachdem man die Bedeutung von „auf der Xbox drucken“ als Fehler definiert hat, wird es zu einem Implementierungs- oder Debugging-Problem, ob dieser Fehler nicht geworfen, sondern verschluckt wird.
    • Das ist kein Verschlucken von Fehlern, sondern in Linux-Terminologie eher, den Userspace nicht kaputtzumachen.
      Es gibt zwei mögliche Behandlungen: einen Fehler ausgeben, weil die Maschine niemals einen Drucker hat, oder eine leere Druckerliste zurückgeben, weil die Maschine niemals einen Drucker hat.
      Beides ist plausibel, aber nur eines davon macht den Userspace nicht kaputt.
    • Wenn man den Text liest, geht es mehr um die User Experience als um die Developer Experience.
      „Laut Alarm zu schlagen“ ist für Tester oder Entwickler gut, für Endnutzer aber weniger.
      Aus Sicht des Endnutzers ist es besser, den Fehler zu verschlucken, als die App abstürzen zu lassen.
    • Es nervt, dass bei einer fehlgeschlagenen Internetverbindung seit Jahrzehnten einfach nur eine Meldung erscheint, dass sie fehlgeschlagen ist.
      Man kann nicht erkennen, was fehlgeschlagen ist: die Software auf meinem Computer, die Hardware, das Ethernet-Kabel oder WLAN, der Switch, der Router, das Kabelmodem, das Internetkabel bis zu meinem Haus, der ISP oder das entfernte System, zu dem ich eine Verbindung herstellen will – daran hat sich überhaupt nichts verbessert.
  • Negative Reaktionen sind zu erwarten, aber genau diese schmutzige Arbeit ist der Grund, warum ein Word-’97-Dokument oder ein vor 30 Jahren für MS-DOS kompiliertes Spiel beim Anklicken so geöffnet wird, wie man es erwartet.
    Abwärtskompatibilität ist immer messy, und entweder man macht sie unvollkommen oder gar nicht.

    • Diesen Refrain hört man über Microsoft oft, aber bei Spielen hatte ich kein Glück.
      Am Ende nutzt man GOG, und GOG virtualisiert letztlich ebenfalls die Umgebung.
      Zum Beispiel glaube ich nicht, dass jemand das originale Sim City erfolgreich unter Windows 11 installieren wird.
    • Eine in Word ’97 erstellte Datei wurde schon vor 25 Jahren auf zwei unterschiedlichen Computern nicht exakt wie erwartet geöffnet.
      Die Formatierung hing von den installierten Druckertreibern ab.
      Eine LaTeX-Datei von vor 35 Jahren funktioniert dagegen heute noch gut.
    • Selbst bei einer Datei von 1997 braucht man Glück, und in irgendeiner Office-App wird sie wahrscheinlich einfach falsch angezeigt.
      Word konnte nicht garantieren, dass sich die Formatierung nicht ändert, selbst wenn man die Datei auf demselben Computer und mit derselben Version erneut öffnet; deshalb habe ich TeX gelernt.
      Bei Spielen hat Microsoft außerdem mit der Einstellung von GFWL zahlreiche Spiele kaputtgemacht.
      Das originale Dark Souls war bis zur erneuten Veröffentlichung auf Steam nicht spielbar, sodass man eine Raubkopie verwenden musste.
    • Auf aktuellen 64-Bit-Windows-Versionen läuft MS-DOS-Software nicht.
      Es erscheint ein Dialog „nicht unterstützt“, und man kann dosbox herunterladen, aber das ist nicht „genau wie erwartet“.
    • Schön wäre es, wenn das wirklich stimmen würde, aber ich hatte enorm viel Mühe, die Spiele aus meiner Kindheit, die ich aufbewahrt hatte, zum Laufen zu bringen.
      Fast jedes Mal habe ich aufgegeben oder sie bei GOG erneut gekauft; im Grunde habe ich also für die Arbeit bezahlt, Kompatibilitätsprobleme aufzuräumen.
  • Nichts ist so frustrierend wie eine Geräte-UI, die andeutet, dass Geräte tatsächlich existieren könnten, dann aber sagt, dass derzeit keine vorhanden sind.
    Am Ende muss man erst Zeit investieren, um herauszufinden, dass diese Geräte gar nicht unterstützt werden und dieser Bildschirm nur ein Mockup war, das jemand gebaut hat.

    • Trotzdem dürfte das weniger frustrierend sein, als wenn die App einfach abstürzt.
      Wenn eine App nicht auf den Fall vorbereitet ist, dass Drucken nicht unterstützt wird, und die Ausgabe eine Exception wirft, stürzt die App vermutlich einfach ab.
      Eine App, die den Fall fehlender Druckunterstützung berücksichtigt, sollte zuerst über eine explizite API prüfen, ob Drucken unterstützt wird, und die Druck-UI nicht anzeigen, wenn es nicht unterstützt wird.
      Der Artikel handelt nicht von solchen Apps, sondern davon, wie man mit Apps umgeht, die vorher nicht prüfen.
      Der Bug liegt in der App, aber eine gute Plattform sollte versuchen, auch schlechte Apps möglichst weiter funktionieren zu lassen, statt sie einfach abstürzen zu lassen.
    • Hier liegt die Verantwortung möglicherweise weniger bei Microsoft als bei den Softwareautoren, die den Druckerfall nicht behandelt haben.
      Microsofts Rolle besteht darin, zu verhindern, dass eine App abstürzt, nur weil der Softwareanbieter Drucker nicht bedacht hat.
  • Dass eine App, wenn sie drucken will, den Benutzer zur Druckerauswahl auffordert und dann eine leere Liste zeigt — offenbar hat Microsoft in 30 Jahren nichts gelernt: https://www.reddit.com/r/hacking/comments/djvzd/windows_nt_l...

  • Die im Artikel vorgeschlagene konkrete Richtung, nämlich dass die Komponente leiden sollte, bevor der Benutzer leidet, ist richtig, aber das Framing ist extrem störend.
    Aussagen wie „Manchmal muss man eine API so machen, dass sie nichts tut“ oder „Es ist falsch, wenn eine Druckfunktion NotSupportedException wirft“ sind absolut kein allgemeiner Rat.
    Das ist ein Hack, um schlechte Clients zu unterstützen; manchmal ist er nötig, aber normal oder verallgemeinerbar ist dieser Rat nicht.
    In solchen Formulierungen sieht man Spuren davon, dass der Schmerz eines Microsoft-Entwicklers verinnerlicht wurde.

    • Es sind keine schlechten Clients, sondern Clients, die geschrieben wurden, bevor du diese Änderung beschlossen hast.
      Wenn sich der Client nicht geändert hat, die API ihn aber kaputtmacht, dann ist nicht der Client schlecht, sondern die API.
    • Wenn eine Softwareplattform von mehr als nur einer Handvoll Entwickler übernommen wird, entstehen zwangsläufig auch schlechte Apps, und dann muss man solche Dinge tun.
      Für jede weit verbreitete Plattform, die Abwärtskompatibilität ernst nimmt, ist das völlig normal und verallgemeinerbar.
      Windows ist das Paradebeispiel, aber dasselbe passiert auch beim Linux-Kernel-ABI, bei glibc, der Webplattform, Java usw.
    • Manchmal muss man eine API implementieren, die bestehende Clients bereits verwenden.
      Man kann die Zeit nicht zurückdrehen und die Clients neu kompilieren oder neu schreiben.
      Wenn ein Client bereits auf NotSupportedException prüft, muss man sie zurückgeben; wenn nicht, braucht man einen anderen Ansatz.
    • Wenn du im Windows-Team mit so einer Haltung aufgetreten wärst, hätte ich dich als Manager vielleicht gefeuert.
      Das hier ist Windows.
      Anwendungen, auf die Benutzer angewiesen sind, dürfen nicht kaputtgemacht werden.
      Wenn es „schlechte“ oder fehlerhaft funktionierende Client-Apps gibt, muss man alle nötigen Workarounds, Shims und Kompatibilitäts-Hacks einsetzen, damit sie wie erwartet funktionieren.
      Selbst wenn man speziellen Speicherverwaltungscode einbauen muss, damit SimCity läuft.
    • Dieser „schlechte Client“ könnte von einer Firma geschrieben worden sein, die vor langer Zeit pleitegegangen ist.
      Dein Kunde ist auf diesen Client angewiesen, und wenn er wegen deiner Änderung nicht mehr läuft, wird er dir die Schuld geben.
  • Hier hängen sich alle an „nichts tun“ und „Fehlerbehandlung“ auf, aber der Artikel scheint nicht gut genug erklärt zu haben, dass es nicht darum geht, jedes Problem zu schlucken und kumbaya zu singen.
    Der eigentliche Kontext ist Emulation und Kompatibilität für Software, die sich nicht mehr ändern wird, und das unterscheidet sich sehr stark von den meisten Situationen.
    Microsoft selbst verwischt diese Grenze oft, was es noch verwirrender macht, aber hier geht es nicht um gewöhnliche Fehlerbehandlung.
    Emulation bedeutet im Kern, zu lügen.
    An eine Xbox kann man tatsächlich keinen Drucker anschließen, unter Linux läuft ein Windows-Spiel, und ein falsches iPhone kann in Wahrheit ein ARM-Server bei AWS sein.
    Wenn man lügt, muss man überzeugend lügen, damit bestehende Anwendungen weiter funktionieren.
    Wenn Microsoft sagt, man könne bestehende Windows-Apps auf die Xbox portieren, und Windows-Apps das Versprechen hatten, drucken zu können, dann muss die Xbox so lügen, dass es möglich aussieht.
    Wenn ein Programm dagegen ein Use-after-free hat und man still so tut, als gäbe es den Bug nicht, ist das keine korrekte Behandlung.
    Denn niemand hat versprochen, dass selbst bestehende Use-after-free-Bugs auf der neuen Plattform buggenau kompatibel bleiben.

    • Im Artikel gibt es keinerlei Kontext, dass es um Emulation für Software geht, die sich nicht ändern wird.
      Das nimmst du nur an, weil diese Interpretation die Position stützt, die du vertreten willst.
      Tatsächlich gilt der Inhalt des Artikels genauso, wenn ich morgen ein Programm für die Xbox schreibe und drucken will.
      Es gibt keine Abgrenzung, dass dieses Verhalten nur für alte, nicht mehr gewartete Software gelten soll.
  • Ich mag diesen Ansatz und mag ihn zugleich nicht.
    Instinktiv gefällt es mir nicht, Probleme durch böswillige Befolgung zu behandeln.
    Andererseits stimme ich völlig zu, dass es eine gute Entscheidung ist, wenn das Ziel darin besteht, mehr Benutzern zu ermöglichen, mehr Software auf der Plattform auszuführen, selbst wenn Drucken kaputt ist.

  • Dieser Kommentarverlauf war seltsam.
    Es gibt eindeutig Leute, die alles hassen, was Microsoft tut.
    Der Kern des Blogs ist, den Weg, Apps (UWP) auf die XBOX zu bringen, möglichst reibungslos zu machen.
    Ohne Neukompilierung, ohne hässliche ifdefs, ohne Zusatzarbeit soll die App „einfach funktionieren“, und danach kann der Entwickler die App an die XBOX-Plattform anpassen.
    Entscheidend ist, dass der Entwickler die App ohne irgendeinen Aufwand auf die XBOX bringen konnte, und das ist sowohl für die Plattform als auch für die Entwickler gut.
    Für den Benutzer ist eine leere Druckerliste ein klares Signal, dass Drucken nicht möglich ist.
    Vor allem stürzt die App nicht ab und zeigt auch nicht den schlimmstmöglichen Fehler wie „Es ist ein Problem aufgetreten. Bitte versuchen Sie es später erneut“ an.
    Diese Meldung ist keine bessere User Experience.
    Der Entwickler kann die App neu kompilieren und eine aussagekräftigere Meldung einbauen, aber dann ist man wieder am Ausgangspunkt.

    • 95 % dieses Threads scheinen den Artikel nicht verstanden zu haben.
      Zum Beispiel geht der Vorwurf, Fehler würden geschluckt, völlig am Kern vorbei.
  • Der zentrale Punkt, den die Kritiker dieses Textes übersehen, ist, dass es hier keine Ausnahmesituation gibt, in der eine Exception geworfen werden müsste.
    An diesem Gerät ist kein Drucker angeschlossen, und da das in diesem Fall per Definition so ist, sollte die App damit sauber umgehen und nicht abstürzen.
    Ein Notebook würde auch keine Exception werfen, nur weil es keinen Zugriff auf einen Drucker hat.

    • Wenn man ein aktuelles Beispiel für ein weit verbreitetes Nicht-Microsoft-Produkt sucht, das die Verfügbarkeit von Druckern falsch behandelt, gibt es gnome-control-center.
      Wenn man in den Einstellungen einen Drucker hinzufügt und während der Installation zum Tab „Color Profiles“ wechselt, stürzt gnome-control-center bei passendem Timing ab.
      Schaut man genauer hin, versucht es, die verfügbaren Drucker aufzulisten; es weiß zwar, dass ein Drucker vorhanden sein müsste, aber die Informationen existieren noch nicht, und deshalb stirbt es einfach.
      Zum Glück reicht es, ein paar Sekunden zu warten, bis GNOME die Druckerinstallation abgeschlossen hat, und die Einstellungen erneut zu öffnen.
      Trotzdem sollte eine zentrale App, die Endnutzern mit unterschiedlichstem Hintergrund dabei helfen soll, den Desktop richtig zu verwenden, in einer idealen Welt niemals abstürzen.
      Über Randbedingungen nachzudenken ist schwierig, und sich vorzustellen, dass auch die Behandlung von Randbedingungen wiederum eigene Randbedingungen hat, ist noch schwieriger.
      Ob richtig oder falsch: Zumindest denkt der Autor tiefer darüber nach als nur „schlechte App, sie sollte neu geschrieben werden, damit sie Wayland unterstützt“.
  • Eine Zeit lang galt es als hervorragende Strategie, dass Browser trotz Fehlern im HTML-Code ihr Bestes taten, um die Seite anzuzeigen.
    Man versuchte, die Absicht des Autors so gut wie möglich zu erraten und weiterzumachen; Fehler seien schlecht, und Nutzer wollten keine Fehler sehen.
    Ich dachte, wir hätten aus dieser Erfahrung gelernt, aber offenbar nicht.

    • Browser verfolgen diese Strategie weiterhin.
      Der Versuch, sie durch strikte Validierung mit XHTML zu ersetzen, scheiterte; stattdessen war HTML5 erfolgreich, indem es zurückging und explizit definierte, wie jede mögliche fehlerhafte Sequenz zu interpretieren ist, sodass Browser sich zumindest konsistent verhalten.
    • Weil Browser bei Eingaben tolerant waren, wurde das moderne Web möglich.
      Hätten frühe Browser sofort einen Fehler angezeigt, sobald sie auf ein unbekanntes Tag stießen, wären neue Browserfunktionen schon bei ihrer Geburt erstickt.
    • Wenn man Hello und World! eingibt, kann man dank der gewonnenen Weisheit nun sehen, ob ein Fehler erscheint.
      Wenn es aber weiterhin korrekt gerendert wird, heißt das entweder, dass wir noch viel zu lernen haben, oder dass es durchaus sinnvoll sein kann, bestimmte Arten von Fehlern elegant zu behandeln und bei Ausnahmesituationen abzustürzen.
    • Die Softwareentwicklung der letzten 20 Jahre war, abgesehen von LLMs, nicht besonders großartig, und auch LLMs wurden durch Zensur ruiniert.
      Wenn man ins Jahr 1999 zurückreisen würde, würde einem vermutlich nicht allzu viel fehlen.
    • Ich frage mich, was wir zu lernen glaubten.