2 Punkte von GN⁺ 2024-02-17 | 2 Kommentare | Auf WhatsApp teilen

Wenn eine API nichts tut, richtig nichts tun

  • Wenn eine API nichts tun soll, ist es wichtig, dass sie auf die richtige Weise nichts tut.
  • Windows verfügt zum Beispiel über eine umfangreiche Druckinfrastruktur, Xbox jedoch nicht.
  • Wenn eine App auf Xbox versucht zu drucken und dabei eine NotSupportedException auslöst, ist das der falsche Weg.
  • Da die App hauptsächlich auf dem PC getestet wurde, wird die Ausnahme beim Ausführen auf Xbox möglicherweise nicht behandelt und die App stürzt ab.
  • Ein besseres Design, um Drucken auf Xbox zu "unterstützen", besteht darin, dass die Druckfunktion erfolgreich ist, aber meldet, dass keine Drucker installiert sind.
  • Wenn der Benutzer zu drucken versucht, wird zwar zur Druckerauswahl aufgefordert, aber die Liste ist leer, sodass der Benutzer erkennt: "Es gibt keinen Drucker" und den Druckauftrag abbricht.
  • Für Apps, die versuchen, einen Drucker zu installieren, kann die Funktion zur Druckerinstallation sofort mit dem Ergebniscode "Der Benutzer hat den Vorgang abgebrochen" zurückkehren.
  • Das Ziel ist, sich so zu verhalten, als würde die Druckfunktion vollständig unterstützt, tatsächlich aber so, als gäbe es einfach keinen Drucker.
  • Auf Systemen, auf denen Drucken überhaupt nicht funktioniert, kann man zusätzlich eine Funktion bereitstellen, die prüft, ob gedruckt werden kann, damit der Druck-Button in der UI ausgeblendet wird.
  • Dieses Verhalten wird als "inert" bezeichnet.
  • Die API-Oberfläche existiert weiterhin und funktioniert gemäß Spezifikation, tut in Wirklichkeit aber nichts.
  • Entscheidend ist, auf die dokumentierte und konsistente Weise nichts zu tun, um Probleme mit bestehendem Code zu minimieren.

Beispiele zum Deaktivieren einer API

  • Es gibt ein Beispiel zum Deaktivieren einer API, die verschiedene Funktionen zum Erzeugen von Widget-Handles, Funktionen mit Widget-Handles als Parameter und Funktionen zum Schließen von Widget-Handles umfasst.
  • Das Team schlug zunächst vor, die API zu deaktivieren, indem CreateWidget zwar erfolgreich ist, aber einen Nullpointer zurückgibt.
  • Dieser Ansatz kann Apps jedoch verwirren: "Der Aufruf war erfolgreich, aber ich habe kein gültiges Handle bekommen?"
  • Auch wenn EnableWidget "ungültiges Handle" zurückgibt, kann das Verwirrung stiften.
  • In der vorhandenen Dokumentation wurde schließlich ein Rückgabewert namens ERROR_CANCELLED gefunden, der bedeutet, dass die Widget-Erstellung vom Benutzer abgebrochen wurde.
  • Daher kann man jedes Mal, wenn eine App versucht, ein Widget zu erzeugen, sagen: "Nein, der Benutzer hat abgebrochen."

Meinung von GN⁺

  • Das Wichtigste an diesem Beitrag ist, dass eine API, wenn sie nichts tut, dies auf eine Weise tun sollte, die weder die Benutzererfahrung beeinträchtigt noch die Kompatibilität mit bestehendem Code gefährdet.
  • Dieser Ansatz unterstreicht für Entwickler die Bedeutung von API-Design und trägt dazu bei, eine benutzerfreundliche Software-Erfahrung bereitzustellen.
  • Der Beitrag zeigt eine sorgfältige Seite des Software Engineerings und liefert ein interessantes Beispiel dafür, wie Apps auch in unerwarteten Umgebungen elegant scheitern können.

2 Kommentare

 
GN⁺ 2024-02-17
Hacker-News-Kommentar
  • Meinung zum „Verschlucken von Fehlern“:

    • Fehler zu verbergen ist keine gute Praxis.
    • Es löst das Problem nicht, sondern macht das Auffinden von Bugs und das Testen schwieriger, indem Mängel in der Software versteckt werden.
    • Das panic von Go ist eine gute Möglichkeit, Programmierfehler beim Testen unübersehbar sichtbar zu machen.
    • Wenn Akteure innerhalb eines Systems versuchen, ihre eigenen Fehler zu verbergen, wird es deutlich schwieriger, Probleme zu erkennen und zu beheben.
  • Meinung zur Abwärtskompatibilität:

    • Abwärtskompatibilität ist immer eine schmutzige Arbeit; die Wahl besteht zwischen „nicht perfekt machen“ und „es gar nicht machen“.
    • Dass sich Word-'97-Dateien oder Spieldateien für MS-DOS heute auf einem Computer per Klick wie erwartet öffnen, liegt genau daran.
  • Beschwerde über UI-Design:

    • Eine UI, die Geräte vorschlägt, die möglicherweise existieren, ist extrem frustrierend.
    • Man verschwendet Zeit damit, Geräte zu suchen, die tatsächlich gar nicht unterstützt werden.
  • Hinweis auf Microsofts mangelnde Lernfähigkeit:

    • Microsoft wiederholt auch nach 30 Jahren noch dieselben Fehler.
    • Wenn eine App bei der Druckersuche eine leere Liste anzeigt, ist das eine Wiederholung früherer Probleme.
  • Meinung zur fehlenden Druckunterstützung der Xbox:

    • Dass die Xbox kein Drucken unterstützt, liegt daran, dass Microsoft es so festgelegt hat.
    • Hardwareseitig besitzt sie die gleichen Druckfähigkeiten wie andere Windows-Geräte.
    • Solche „Lösungen“ sind Probleme, die aus irrationalen Entscheidungen von Microsoft entstehen.
  • Ratschlag zur Nutzung von APIs:

    • Es stimmt zwar, dass eine Komponente das Problem vor dem Nutzer erleben sollte, aber mit der Formulierung des Autors kann man nicht einverstanden sein.
    • Es ist nicht falsch, wenn eine Druckfunktion eine NotSupported­Exception auslöst.
    • Was der Autor beschreibt, ist ein Hack, um fehlerhafte Clients zu unterstützen.
  • Gefühl der „böswilligen Regelbefolgung“:

    • Die Art, wie mit dem Problem umgegangen wird, gefällt einem und gefällt einem zugleich nicht.
    • Wenn das Ziel jedoch ist, dass mehr Nutzer auf der Plattform mehr Software ausführen können, dann ist diese Methode gut.
  • Positive Meinung zur Sicherheit:

    • Das korrekte Ignorieren von API-Aufrufen verhindert, dass Programme schädlichere Aktionen ausführen.
  • Rückblick auf die Browser-Strategie:

    • Die Strategie, eine Seite trotz Fehlern im HTML-Code nach bestem Wissen anzuzeigen, galt einmal als gute Strategie.
    • Nutzer wollen keine Fehlermeldungen, und aus dieser Erfahrung hätte man lernen sollen.
  • Missverständnis der Kritiker bei der Ausnahmebehandlung:

    • Es gibt einen Punkt, den Kritiker übersehen, wenn es keinen Anlass gibt, eine Ausnahme auszulösen.
    • Wenn ein Gerät (Drucker) nicht verbunden ist, sollte die App diese Situation sauber behandeln und nicht abstürzen.
 
GN⁺ 4 일 전
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