Teilen über


Fehlerbehandlung

Anmerkung

Das in diesem Artikel beschriebene Verhalten ist nur verfügbar, wenn die Vorschaufunktion Fehlerverwaltung auf Formelebene über Einstellungen>Bevorstehende Funktionen>Vorschau aktiviert ist. Weitere Informationen: Steuern, welche Funktionen aktiviert sind

Fehler passieren. Netzwerke fallen aus, Speicher füllt sich, unerwartete Werte treten auf. Es ist wichtig, dass Ihre Logik ordnungsgemäß funktioniert, auch wenn es zu Fehlern kommt.

Standardmäßig fließen Fehler durch die Formeln einer App und werden dem Endbenutzer der App gemeldet. Auf diese Weise weiß der Endbenutzer, dass etwas Unerwartetes passiert ist, kann das Problem möglicherweise selbst mit einer anderen Eingabe beheben oder es dem Besitzer der App melden.

Als App-Ersteller können Sie das Verhalten bei Fehlern in Ihrer App steuern:

  • Fehlererkennung und ‑behandlung. Wenn die Möglichkeit eines Fehlers besteht, können die Formeln der App so geschrieben werden, dass die Fehlerbedingung erkannt und der Vorgang wiederholt wird. Der Endbenutzer muss sich keine Sorgen machen, dass ein Fehler aufgetreten ist, weil der Ersteller diese Möglichkeit berücksichtigt hat. Dies wird mit den Funktionen IfError, IsError und IsErrorOrBlank innerhalb einer Formel durchgeführt.
  • Fehlerberichterstattung. Wenn ein Fehler nicht in der Formel bearbeitet wird, in der er aufgetreten ist, wird er an den App.OnError-Handler weitergeleitet. Hier kann der Fehler nicht mehr ersetzt werden, da er bereits aufgetreten und Teil von Formelberechnungen ist. Aber Sie können App.OnError verwenden, um zu steuern, wie der Fehler an den Endbenutzer gemeldet wird, einschließlich der vollständigen Unterdrückung der Fehlerberichterstattung. App.OnError bietet zudem einen gemeinsamen Engpass für die Fehlerberichterstattung in der gesamten App.
  • Erstellen und erneutes Auslösen eines Fehlers. Sie können eine Fehlerbedingung auch mit Ihrer eigenen Logik erkennen; eine Bedingung, die spezifisch für Ihre App ist. Verwenden Sie die Error-Funktion zum Erstellen benutzerdefinierter Fehler. Die Error-Funktion wird auch verwendet, um einen Fehler nach der Abfrage in IfError oder App.OnError erneut auszulösen.

Erste Schritte

Beginnen wir mit einem einfachen Beispiel.

  1. Erstellen Sei einen neuen Bildschirm in einer Power Apps Canvas-App.
  2. Fügen Sie ein Text input-Steuerelement ein. Es hat standardmäßig den Namen TextInput1.
  3. Fügen Sie ein Label-Steuerelement ein.
  4. Legen Sie die Text-Eigenschaft des Label-Steuerelements auf die folgende Formel fest:
1/Value( TextInput1.Text )

Fehlerbanner mit der Meldung „Der Wert kann nicht in eine Zahl umgewandelt werden“ für das Steuerelement „Texteingabe“

Es tritt ein Fehler auf, da der Standardtext eines Text input-Steuerelements "Text input" ist, was nicht in eine Zahl konvertiert werden kann. Dies ist allgemein von Vorteil: Der Endbenutzer erhält eine Benachrichtigung, dass etwas in der App nicht wie erwartet funktioniert.

Natürlich möchten wir nicht, dass der Benutzer bei jedem Starten dieser App von einem Fehler begrüßt wird. Wahrscheinlich ist "Text input" sowieso nicht der richtige Standardwert für das Texteingabefeld. Um dies zu beheben, ändern wir die Default-Eigenschaft des Text input-Steuerelements wie folgt:

Blank()

Fehlerbanner mit „Division durch Null“ angezeigt

Hmm, jetzt wird ein anderer Fehler angezeigt. Bei mathematischen Vorgängen mit leer, wie z. B. Division, wird erzwungen, dass der leere Wert Null ist. Dies verursacht den Fehler, dass durch Null dividiert wird. Um dies zu beheben, müssen wir entscheiden, welches Verhalten für diese Situation in der App angemessen ist. Die Lösung könnte sein, leer anzuzeigen, wenn die Texteingabe leer ist. Dies können wir erreichen, indem wir unsere Formel mit der IfError-Funktion umschließen:

IfError( 1/Value( TextInput1.Text ), Blank() )

Es wird kein Fehlerbanner angezeigt, ein Fehler aufgrund eines Leerwerts wurde durch ein Leerzeichen ersetzt

Jetzt wird der Fehler durch einen gültigen Wert ersetzt und das Fehlerbanner ist verschwunden. Aber wir sind vielleicht über das Ziel hinausgeschossen, denn unsere IfError-Funktion deckt alle Fehler ab, einschließlich der Eingabe eines falschen Werts wie "hello". Wir können dies beheben, indem wir unsere IfError-Funktion so einstellen, dass sie nur den Division-durch-Null-Fehler bearbeitet und alle anderen Fehler erneut auslöst:

IfError( 1/Value( TextInput1.Text ), 
         If( FirstError.Kind = ErrorKind.Div0, Blank(), Error( FirstError ) ) )

Es wird kein Fehlerbanner angezeigt, ein Fehler, der speziell auf die Division durch Null zurückzuführen ist, wurde durch ein Leerzeichen ersetzt, andernfalls wird der Fehler erneut ausgelöst

Wir führen unsere App also nochmal aus und testen verschiedene Werte.

Wenn kein Wert eingegeben ist, wie z. B. beim Start der App, wird keine Antwort angezeigt, da der Standardwert leer ist – aber es wird auch kein Fehler angezeigt, da IfError den Division-durch-Null-Fehler ersetzt.

Keine Antwort angezeigt und kein Fehlerbanner

Wenn wir eine 4 eingeben, erhalten wir das erwartete Ergebnis von 0,25:

0,25 angezeigt und kein Fehlerbanner

Und wenn wir einen unzulässigen Wert eingeben, z. B. hello, erhalten wir ein Fehlerbanner:

kein Wert angezeigt und Fehlerbanner für die Unfähigkeit, „Hallo“ in eine Zahl zu konvertieren

Dies ist ein einfaches Beispiel zur Einführung. Die Fehlerbehandlung kann je nach den Anforderungen der App auf viele verschiedene Arten erfolgen:

  1. Anstelle eines Fehlerbanners hätten wir "#Error" im Label-Steuerelement mit der Formel anzeigen können. Damit die Typen von Ersetzungen mit dem ersten Argument von IfError kompatibel bleiben, müssen wir das numerische Ergebnis explizit mit der Text-Funktion in eine Textzeichenfolge konvertieren.
    IfError( Text( 1/Value( TextInput1.Text ) ), 
             If( FirstError.Kind = ErrorKind.Div0, Blank(), "#Error" )
    
    kein Fehlerbanner und stattdessen wird #Fehler als Ergebnis angezeigt
  2. Anstatt diese spezifische Instanz mit IfError zu umschließen, hätten wir einen zentralisierten App.OnError-Handler schreiben können. Wir können die angezeigte Zeichenfolge nicht durch "#Error" ersetzen, da der Fehler bereits aufgetreten ist und App.OnError nur zur Steuerung der Berichterstellung bereitgestellt wird.
    If( FirstError.Kind <> ErrorKind.Div0, Error( FirstError ) )
    

Fehlerweitergabe

Ähnlich wie in Excel fließen Fehler durch Formeln. Wenn in Excel beispielsweise die Zelle A1 die Formel =1/0 enthält, zeigt A1 den Fehlerwert #DIV0! an:

Excel-Tabellenblatt mit A1=1/0 und #DIV/0! in der Zelle

Wenn Zelle A2 mit einer Formel wie =A1*2 auf A1 verweist, wird der Fehler auch durch diese Formel weitergegeben:

Excel-Tabelle mit A2=A1*2 und #DIV/0! in der Zelle

Der Fehler ersetzt den Wert, der sonst berechnet worden wären. Es ist kein Ergebnis für die Multiplikation in Zelle A2 vorhanden, sondern nur den Fehler aus der Division in A1.

Power Fx funktioniert auf dieselbe Weise. Wenn ein Fehler als Argument für eine Funktion oder einen Operator angegeben wird, findet der Vorgang im Allgemeinen nicht statt und der Eingabefehler fließt als Ergebnis den Vorgang. Mid( Text( 1/0 ), 1, 1 ) gibt beispielsweise einen Division-durch-Null-Fehler zurück, da der innerste Fehler die Text-Funktion und die Mid-Funktion durchläuft:

Fehlerbanner mit ungültigem Vorgang: Division durch Null

Allgemein fließen Fehler nicht durch Power Apps-Steuerelementeigenschaften. Ergänzen wir nun das vorherige Beispiel um ein zusätzliches Steuerelement, das anzeigt, ob die Text-Eigenschaft des ersten Labels einen Fehlerzustand aufweist:

Beim zweiten Label Steuerelement wird kein Fehler mehr angezeigt

Es ist in Ordnung, dass Fehler nicht durch ein Steuerelement weitergegeben werden, da das System Fehler bei der Eingabe für alle Steuerelementeigenschaften beobachtet. Der Fehler geht nicht verloren.

Die meisten Funktionen und Operatoren folgen der Regel „Fehler rein, Fehler raus“, aber es gibt einige Ausnahmen. Die Funktionen IsError, IsErrorOrBlank und IfError sind für die Arbeit mit Fehlern konzipiert, sodass sie möglicherweise keinen Fehler zurückgeben, selbst wenn einer an sie übergeben wird.

Fehler beobachten

Fehler werden nicht beobachtet, bis ihr Wert verwendet wird.

Daher geben die Funktionen If und Select möglicherweise auch keinen Fehler zurück, wenn ihnen einer übergeben wird. Betrachten Sie die Formel If( false, 1/0, 3 ). In dieser Formel ist ein Division-durch-Null-Fehler vorhanden, aber da If diese Verzweigung wegen false nicht einschlägt, melden Power Fx und Power Apps keinen Fehler:

Es wird kein Fehlerbanner angezeigt, wenn die Funktion If in der Eigenschaft Label Text verwendet wird

Bei Verwendung der Set-Funktion mit einem Fehler wird kein Fehler an der Stelle gemeldet, an der der Fehler in der Variablen eingefügt wird. In Power Apps haben wir hier beispielsweise eine Formel in App.OnStart, die einen Division-durch-Null-Fehler in die Variable x einfügt:

Es wird kein Fehlerbanner angezeigt, wenn die Funktion Set in App.OnStart aufgerufen wird

Es wird kein Fehler gemeldet, da x nicht referenziert wird. Sobald wir jedoch ein Label-Steuerelement hinzufügen und seine Text-Eigenschaft auf x festlegen, wird der Fehler angezeigt:

Fehlerbanner mit dem Label-Steuerelement, das auf die Variable x verweist

Sie können Fehler innerhalb einer Formel mit den Funktionen IfError, IsError und IsErrorOrBlank beobachten. Mit diesen Funktionen können Sie einen alternativen Wert zurückgeben, alternative Maßnahmen ergreifen oder den Fehler ändern, bevor er beobachtet und gemeldet wird.

Fehler berichten

Nachdem ein Fehler beobachtet wurde, besteht der nächste Schritt darin, den Fehler an den Endbenutzer zu melden.

Im Gegensatz zu Excel gibt es nicht immer einen geeigneten Ort, um ein Fehlerergebnis anzuzeigen, da das Ergebnis einer Formel eine Eigenschaft wie die X‑ und Y-Koordinaten eines Steuerelements steuern kann, und es dabei keinen geeigneten Ort zur Anzeige von Text gibt. Jeder Power Fx-Host steuert, wie Fehler dem Endbenutzer letztendlich angezeigt werden und wie viel Kontrolle der Ersteller über diesen Prozess hat. In Power Apps wird ein Fehlerbanner angezeigt, und App.OnError wird verwendet, um die Fehlerberichterstattung zu steuern.

Beachten Sie, dass App.OnError den Fehler nicht auf dieselbe Weise wie IfError ersetzen kann. Am Punkt der Ausführung von App.OnError ist der Fehler bereits aufgetreten, und das Ergebnis wurde durch andere Formeln weitergegeben. App.OnError steuert nur, wie der Fehler dem Endbenutzer gemeldet wird, und bietet dem Ersteller einen Hook, um den Fehler bei Bedarf zu protokollieren.

Die Bereichsvariablen FirstError und AllErrors liefern Kontextinformationen zu etwaigen Fehlern. Sie geben Aufschluss über die Fehlerart, seinen Ursprung und wo er beobachtet wurde.

Nach einem Fehler beenden

Verhaltensformeln unterstützen das Ergreifen von Maßnahmen, Ändern von Datenbanken und Ändern des Status. Diese Formeln ermöglichen es, mehr als eine Aktion in einer Sequenz auszuführen, indem der ;-Verkettungsoperator (oder ;;, je nach Gebietsschema) verwendet wird.

In diesem Fall zeigt das Grid-Steuerelement beispielsweise, was in der Tabelle T steht. Jede Schaltflächenauswahl ändert den Status in dieser Tabelle mit zwei Patch-Aufrufen:

Animation, die zeigt, wie die beiden Datensätze in Tabelle T nach jedem Klick auf eine Schaltfläche mit Zufallszahlen aktualisiert werden

In einer verketteten Verhaltensformel werden Aktionen nicht nach dem ersten Fehler beendet. Nun ändern wir unser Beispiel so, dass im ersten Patch-Aufruf eine ungültige Indexnummer übergeben wird. Der zweite Patch läuft trotz dieses früheren Fehlers weiter. Der erste Fehler wird dem Endbenutzer gemeldet und als Fehler in Studio auf dem Steuerelement angezeigt:

Animation, die zeigt, dass nur der zweite Datensatz in Tabelle T nach jedem Klick auf die Schaltfläche mit Zufallszahlen aktualisiert wird, während der erste Datensatz zu einem Fehler führt

IfError kann verwendet werden, um die Ausführung nach einem Fehler zu beenden. Ähnlich wie bei der If-Funktion bietet das dritte Argument dieser Funktion einen Platz für Aktionen, die nur ausgeführt werden sollen, wenn kein Fehler vorliegt:

Animation, die zeigt, dass keine Änderungen an einem der beiden Datensätze in Tabelle T vorgenommen wurden, da der IfError den zweiten Vorgang nach einem Fehler nicht abschließen kann

Wenn während einer der Iterationen von ForAll ein Fehler auftritt, werden die restlichen Iterationen nicht beendet. ForAll ist so konzipiert, dass jede Iteration unabhängig ausgeführt wird, was eine parallele Ausführung ermöglicht. Wenn ForAll abgeschlossen ist, wird ein Fehler zurückgegeben, der alle aufgetretenen Fehler enthält (durch Untersuchen von AllErrors in IfError oder App.OnError).

Die folgende Formel führt beispielsweise dazu, dass ForAll zwei Fehler zurückgibt (für die Division durch Null für Value von 0 – zweimal), und Collection hat drei Datensätze (für den Fall, in dem Value nicht 0 ist): [1, 2, 3].

Clear( Collection ); 
ForAll( [1,0,2,0,3], If( 1/Value > 0, Collect( Collection, Value ) ) );

Mit mehreren Fehlern arbeiten

Da eine Verhaltensformel mehr als eine Aktion ausführen kann, kann es dabei auch zu mehr als einem Fehler kommen.

Standardmäßig wird der erste Fehler an den Endbenutzer gemeldet. In diesem Beispiel schlagen beide Patch-Aufrufe fehl, der zweite mit einem Division-durch-Null-Fehler. Nur der erste Fehler (zu Index) wird dem Benutzer angezeigt:

Erster Indexfehler wird in einem Fehlerbanner angezeigt, der zweite Fehler wird nicht gemeldet

Die IfError-Funktion und App.OnError können auf alle Fehler zugreifen, die mit der Bereichsvariablen AllErrors aufgetreten sind. In diesem Fall können wir dies auf eine globale Variable festlegen und uns beide aufgetretenen Fehler ansehen. Sie erscheinen in derselben Reihenfolge in der Tabelle, in der sie auch aufgetreten sind:

Erfassen der Fehler in der globalen Variable PatchErrors, wo wir sehen können, dass beide Fehler vorhanden sind

Mehrere Fehler können ebenso in verhaltensunabhängigen Formeln zurückgegeben werden. Die Verwendung der Patch-Funktion kann beispielsweise mehrere Fehler zurückgeben, wenn ein Stapel von Datensätzen aktualisiert werden soll – ein Fehler für jeden fehlgeschlagenen Datensatz.

Fehler in Tabellen

Wie wir bereits gelernt haben, können Fehler in Variablen gespeichert werden. Fehler können auch in Datenstrukturen wie Tabellen enthalten sein. Dies ist wichtig, damit ein Fehler in einem beliebigen Datensatz nicht die gesamte Tabelle ungültig machen kann.

Betrachten Sie beispielsweise dieses „Data table“-Steuerelement in Power Apps:

Die Datentabelle zeigt einen Fehler für das Feld Reciprocal bei einer Eingabe von 0 an, was zu einem Fehler bei der Division durch Null führt

Bei der Berechnung in AddColumns ist für einen der Werte ein Division-durch-Null-Fehler aufgetreten. Für diesen einen Datensatz hat die Spalte Reciprocal einen Fehlerwert (Division durch Null), die anderen Datensätze jedoch nicht – sie sind fehlerfrei. IsError( Index( output, 2 ) ) gibt „false“ zurück, und IsError( Index( output, 2 ).Value ) gibt „true“ zurück.

Wenn beim Filtern einer Tabelle ein Fehler auftritt, gilt der gesamte Datensatz als Fehler, wird aber dennoch im Ergebnis zurückgegeben, damit der Endbenutzer weiß, dass etwas vorhanden war und ein Problem vorliegt.

Sehen wir uns dieses Beispiel an. Hier weist die ursprüngliche Tabelle keine Fehler auf, aber beim Filtern entsteht ein Fehler, wann immer Wert gleich 0 ist:

Datentabelle mit Fehlern für zwei Datensätze, die durch die Filterkriterien nicht verarbeitet werden konnten

Die Werte -5 und -3 werden korrekt gefiltert. Die Werte 0 führen zu einem Fehler bei der Filterverarbeitung, sodass unklar ist, ob der Datensatz im Ergebnis aufgenommen werden soll oder nicht. Um die Transparenz für Endbenutzer zu maximieren und Erstellern beim Debuggen zu helfen, fügen wir anstelle des Originals einen Fehlerdatensatz hinzu. In diesem Fall gibt IsError( Index( output, 2 ) ) „true“ zurück.

Fehler in der Datenquelle

Die Funktionen, die Daten in Datenquellen ändern, wie Patch, Collect, Remove, RemoveIf, Update, UpdateIf und SubmitForm, melden Fehler auf zwei Arten:

  • Jede dieser Funktionen gibt als Ergebnis des Vorgangs einen Fehlerwert zurück. Wie gewohnt können Fehler mit IsError erkannt und mit IfError und App.OnError ersetzt bzw. unterdrückt werden.
  • Nach dem Vorgang gibt die Funktion Errors auch die Fehler für vorherige Vorgänge zurück. Dies kann nützlich sein, um die Fehlermeldung auf einem Formularbildschirm anzuzeigen, ohne den Fehler in einer Zustandsvariablen erfassen zu müssen.

Diese Formel sucht beispielsweise nach einem Fehler von Collect und zeigt eine benutzerdefinierte Fehlermeldung an:

IfError( Collect( Names, { Name: "duplicate" } ),
         Notify( $"OOPS: { FirstError.Message }", NotificationType.Warning ) )

Die Errors-Funktion gibt auch Informationen zu vergangenen Fehlern während Laufzeitvorgängen zurück. Dies kann nützlich sein, um einen Fehler auf einem Formularbildschirm anzuzeigen, ohne ihn in einer Zustandsvariablen erfassen zu müssen.

Fehler erneut auslösen

Manchmal werden einige potenzielle Fehler erwartet und können getrost ignoriert werden. Wenn in IfError und App.OnError ein Fehler erkannt wird, der an den nächsthöheren Handler weitergegeben werden soll, kann er mit Error( AllErrors ) erneut ausgelöst werden.

Eigene Fehler erstellen

Mit der Error-Funktion können Sie auch eigene Fehler erstellen.

Für das Erstellen eigener Fehler wird empfohlen, dass Sie Werte über 1000 verwenden, um potenzielle Konflikte mit zukünftigen Systemfehlerwerten zu vermeiden.

ErrorKind-Enumerationswerte

ErrorKind-Enumeration Wert Beschreibung
AnalysisError 18 Systemfehler. Bei der Compiler-Analyse ist ein Fehler aufgetreten.
BadLanguageCode 14 Ein ungültiger oder nicht erkannter Sprachcode wurde verwendet.
BadRegex 15 Ungültiger regulärer Ausdruck. Überprüfen Sie die Syntax, die mit den Funktionen IsMatch, Match oder MatchAll verwendet wird.
Conflict 6 Der aktualisierte Datensatz wurde bereits in der Quelle geändert und der Konflikt muss gelöst werden. Eine gängige Lösung besteht darin, alle lokalen Änderungen zu speichern, den Datensatz zu aktualisieren und die Änderungen erneut anzuwenden.
ConstraintViolated 8 Der Datensatz hat eine Einschränkungsprüfung auf dem Server nicht durchlaufen.
CreatePermission 3 Der Benutzer hat keine Berechtigung zum Erstellen eines Datensatzes für die Datenquelle. Dies passiert beispielsweise, wenn die Collect-Funktion aufgerufen wurde.
DeletePermissions 5 Der Benutzer hat keine Berechtigung zum Löschen eines Datensatzes für die Datenquelle. Dies passiert beispielsweise, wenn die Remove-Funktion aufgerufen wurde.
Div0 13 Division durch Null.
EditPermissions 4 Der Benutzer hat keine Berechtigung zum Erstellen eines Datensatzes für die Datenquelle. Dies passiert beispielsweise, wenn die Patch-Funktion aufgerufen wurde.
GeneratedValue 9 An den Server wurde fälschlicherweise ein Wert für ein Feld übergeben, das automatisch vom Server berechnet wird.
InvalidFunctionUsage 16 Ungültige Verwendung einer Funktion. Oft ist mindestens ein Argument der Funktion fehlerhaft oder wird auf ungültige Weise verwendet.
FileNotFound 17 Der SaveData-Speicher wurde nicht gefunden.
InsufficientMemory 21 Für diesen Vorgang ist nicht genügend Arbeitsspeicher oder Speicherplatz auf dem Gerät vorhanden.
InvalidArgument 25 Ein ungültiges Argument wurde an eine Funktion übergeben.
Internal 26 Systemfehler. Bei einer der Funktionen ist ein internes Problem aufgetreten.
MissingRequired 2 Bei einem Datensatz fehlte ein erforderliches Feld.
Network 23 Bei der Netzwerkkommunikation ist ein Fehler aufgetreten.
None 0 Systemfehler. Es liegt kein Fehler vor.
NotApplicable 27 Es ist kein Wert verfügbar. Nützlich, um einen leeren Wert, der in numerischen Berechnungen als Null behandelt werden kann, von leeren Werten zu unterscheiden, die bei Verwendung des Werts als potenzielles Problem gekennzeichnet werden sollten.
NotFound 7 Datensatz wurde nicht gefunden. Dies kann sich beispielsweise auf den Datensatz beziehen, der in der Patch-Funktion geändert werden soll.
NotSupported 20 Der Vorgang wird von diesem Spieler oder Gerät nicht unterstützt.
Numeric 24 Eine numerische Funktion wurde nicht ordnungsgemäß verwendet. Beispiel: Sqrt mit -1.
QuotaExceeded 22 Speicherplatz wurde überschritten.
ReadOnlyValue 10 Die Spalte ist schreibgeschützt und kann nicht geändert werden.
ReadPermission 19 Der Benutzer hat keine Berechtigung zum Lesen eines Datensatzes für die Datenquelle.
Sync 1 Von der Datenquelle wurde ein Fehler gemeldet. Überprüfen Sie die Meldungsspalte auf weitere Informationen.
Unknown 12 Es ist ein unbekannter Fehler aufgetreten.
Validation 11 Der Datensatz hat eine Validierungsprüfung nicht bestanden.