Share via


Foutafhandeling

Opmerking

Het gedrag dat in dit artikel wordt beschreven, is alleen beschikbaar wanneer de preview-functie Foutbeheer op formuleniveau in Instellingen>Aanstaande functies>Preview is ingeschakeld. Meer informatie: Controleren welke functies zijn ingeschakeld

Fouten vinden plaats. Netwerken vallen uit, opslagruimtes raken vol, onverwachte waarden stromen binnen. Het is belangrijk dat uw logica goed blijft werken ondanks mogelijke problemen.

Standaard stromen fouten door de formules van een app en worden ze gerapporteerd aan de eindgebruiker van de app. Zo weten eindgebruikers dat er iets onverwachts is gebeurd, kunnen ze het probleem eventueel zelf oplossen met een andere invoer of kan het probleem worden gemeld bij de eigenaar van de app.

App-makers hebben controle over fouten in de app:

  • Fouten detecteren en oplossen. Als de kans bestaat dat er een fout optreedt, kunnen er formules in de app worden geschreven om de foutconditie te detecteren en de bewerking opnieuw uit te voeren. De eindgebruiker hoeft zich geen zorgen te maken dat er een fout is opgetreden omdat de maker rekening heeft gehouden met de mogelijkheid. Dit wordt gedaan met de functies IfError, IsError en IsErrorOrBlank binnen een formule.
  • Fouten rapporteren. Als een fout niet wordt afgehandeld in de formule waarin deze is aangetroffen, wordt de fout doorgestuurd naar de handler App.OnError. Hier kan de fout niet meer worden vervangen omdat deze al is opgetreden en deel uitmaakt van formuleberekeningen. Maar u kunt App.OnError gebruiken om te bepalen hoe de fout wordt gerapporteerd aan de eindgebruiker, ook kan de foutrapportage helemaal worden onderdrukt. App.OnError biedt ook een algemene choke aanwijzen voor foutrapportage in de gehele app.
  • Een fout maken en opnieuw genereren. Ten slotte kunt u een foutconditie detecteren met uw eigen logica, een conditie die specifiek is voor uw app. Gebruik de functie Error om aangepaste fouten te maken. De functie Error wordt ook gebruikt om een fout opnieuw te genereren nadat deze is opgevraagd in IfError of App.OnError.

Aan de slag

We beginnen met een eenvoudig voorbeeld.

  1. Maak een nieuw scherm in een Power Apps-canvas app.
  2. Voeg een besturingselement TextInput in. Standaard wordt de naam TextInput1 gebruikt.
  3. Voeg een besturingselement Label in.
  4. Stel de eigenschap Text van het besturingselement Label in op de formule
1/Value( TextInput1.Text )

Foutbanner weergegeven met

Er is een fout opgetreden omdat de standaardtekst van een TextInput-besturingselement "Text input" is, wat niet kan worden omgezet in een getal. Standaard is dit een goede zaak: de eindgebruiker krijgt een melding dat er iets niet werkt zoals verwacht in de app.

We willen natuurlijk niet dat de gebruiker elke keer een foutmelding krijgt als deze app wordt gestart. Waarschijnlijk is "Text input" toch niet de juiste standaardinstelling voor het tekstinvoervak. Probeer dit te verhelpen door de eigenschap Default van het besturingselement TextInput te veranderen in:

Blank()

Foutbanner weergegeven met

Nu treedt een andere fout op. Wiskundige bewerkingen met blank, zoals een deling, staan geen andere blanco waarde dan nul toe. En dat zorgt nu voor een deling door nul-fout. Om dit te verhelpen, moeten we beslissen wat het juiste gedrag is voor deze situatie in deze app. Het antwoord kan zijn om een lege waarde weer te geven wanneer de tekstinvoer leeg is. We kunnen dit bereiken door onze formule in te pakken met de functie IfError:

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

Er wordt geen foutbanner weergegeven, een fout als gevolg van een lege waarde is vervangen door een lege waarde

Nu is de fout vervangen door een geldige waarde en is de foutbanner verdwenen. Maar misschien gaat dit te ver. De functie IfError dekt alle fouten, inclusief het typen van een onjuiste waarde zoals "hello". We kunnen dit oplossen door IfError alleen in te stellen voor de deling door nul-fout en alle andere fouten opnieuw te genereren:

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

Er wordt geen foutbanner weergegeven, een fout die specifiek te wijten is aan deling door nul is vervangen door een spatie, anders wordt de fout opnieuw gegenereerd

We gaan nu onze app uitvoeren en een aantal verschillende waarden proberen.

Zonder een waarde, zoals wanneer de app start, wordt er geen antwoord weergegeven omdat de standaardwaarde leeg is, maar er wordt ook geen fout weergegeven als IfError de deling door nul-fout vervangt.

Geen antwoord weergegeven en geen foutbanner

Als we een 4 invoeren, krijgen we het verwachte resultaat van 0,25:

0,25 weergegeven en geen foutbanner

En als we een onjuiste waarde invoeren, zoals hello, krijgen we een foutmelding:

Er wordt geen waarde weergegeven en er wordt een foutbanner weergegeven omdat

Dit is een eenvoudig voorbeeld. Foutafhandeling kan op veel verschillende manieren worden gedaan, afhankelijk van de behoeften van de app.

  1. In plaats van een foutbanner kan bijvoorbeeld "#Error" worden getoond in het labelbesturingselement van de formule. Om de vervangingstypen compatibel te houden met het eerste argument van IfError moet het numerieke resultaat expliciet worden geconverteerd naar een tekenreeks met de functie Text.
    IfError( Text( 1/Value( TextInput1.Text ) ), 
             If( FirstError.Kind = ErrorKind.Div0, Blank(), "#Error" )
    
    Geen foutbanner en in plaats daarvan wordt #Error weergegeven als resultaat
  2. In plaats van dit specifieke exemplaar in te pakken met IfError, kan ook een gecentraliseerde App.OnError-handler worden geschreven. We kunnen de getoonde tekenreeks niet vervangen door '#Error' omdat de fout al is opgetreden en App.OnError alleen wordt gebruikt voor de rapportage.
    If( FirstError.Kind <> ErrorKind.Div0, Error( FirstError ) )
    

Fouten doorgeven

Fouten stromen door formules net zoals in Excel. Als in Excel de cel A1 bijvoorbeeld de formule =1/0 bevat, zal A1 de foutwaarde #DIV0! weergeven:

Excel-spreadsheet met A1=1/0 en #DIV/0! weergegeven in de cel

Als cel A2 verwijst naar A1 met een formule zoals =A1*2, dan verspreidt de fout zich ook via die formule:

Excel-spreadsheet met A2=A1*2 en #DIV/0! weergegeven in de cel

De fout vervangt de waarde die anders zou zijn berekend. Er is geen resultaat voor de vermenigvuldiging in cel A2, alleen de fout van de deling in A1.

Power Fx werkt op dezelfde manier. Als er een fout wordt opgegeven als argument voor een functie of operator, vindt de bewerking gewoonlijk niet plaats en wordt de invoerfout doorgegeven als resultaat van de bewerking. Met Mid( Text( 1/0 ), 1, 1 ) wordt bijvoorbeeld een delen door nul-fout geretourneerd, aangezien de binnenste fout de functies Text en Mid passeert:

Foutbanner met ongeldige bewerking: delen door nul

Over het algemeen stromen fouten niet door eigenschappen van Power Apps-besturingselementen. Laten we het vorige voorbeeld uitbreiden met een extra besturingselement dat wordt weergegeven als de Text-eigenschap van het eerste label een foutstatus is:

Geen fout weergegeven bij tweede labelcontrole

Het is prima dat fouten zich niet verspreiden via een besturingselement, omdat het systeem dan fouten in de invoer van alle besturingselementeigenschappen kan waarnemen. De fout gaat niet verloren.

De meeste functies en operators volgen de regel 'fout in, fout uit', maar er zijn enkele uitzonderingen. De functies IsError, IsErrorOrBlank en IfError zijn ontworpen om met fouten te werken, zodat ze mogelijk geen fout retourneren, zelfs niet als de fout in deze functies wordt doorgegeven.

Fouten waarnemen

Fouten worden pas waargenomen als hun waarde wordt gebruikt.

Het resultaat is dat de functies If en Select mogelijk ook geen fout retourneren als een fout wordt doorgegeven. Bekijk de formule If( false, 1/0, 3 ). Er zit een deling door nul-fout in deze formule, maar aangezien de If die vertakking niet volgt vanwege false, wordt in Power Fx en Power Apps geen fout gerapporteerd:

Geen foutbanner weergegeven met If-functie in label Text-eigenschap

Het gebruik van de functie Set met een fout rapporteert geen fout als de fout in de variabele wordt geplaatst. Bekijk formule bijvoorbeeld in Power Apps deze formule in App.OnStart die een deling door nul-fout in de variabele x plaatst:

Er wordt geen foutbanner weergegeven met Set function call in App.OnStart

Er wordt geen fout gerapporteerd, omdat er niet naar x wordt verwezen. Als echter een labelbesturingselement wordt toegevoegd en de eigenschap Text wordt ingesteld op x, wordt de fout wel weergegeven:

Foutbanner weergegeven met labelbesturingselement dat verwijst naar de variabele x

U kunt fouten waarnemen met een formule voor de functies IfError, IsError en IsErrorOrBlank. Met deze functies kunt u een alternatieve waarde retourneren, alternatieve actie ondernemen of de fout wijzigen voordat deze wordt waargenomen en gerapporteerd.

Fouten rapporteren

Nadat een fout is geconstateerd, is de volgende stap het melden van de fout aan de eindgebruiker.

In tegenstelling tot Excel is er niet altijd een geschikte plaats om een foutresultaat weer te geven. Het resultaat van een formule kan een eigenschap aansturen zoals de X- en Y-coördinaten van een besturingselement, waarvoor er geen geschikte plaats is om tekst weer te geven. Elke Power Fx-host bepaalt hoe fouten uiteindelijk worden weergegeven aan de eindgebruiker en hoeveel controle de maker heeft over dit proces. In Power Apps wordt een foutbanner getoond en App.OnError wordt gebruikt om te bepalen hoe de fout wordt gerapporteerd.

Het is belangrijk op te merken dat App.OnError de fout niet op dezelfde manier kan vervangen als IfError. Op het moment dat App.OnError wordt uitgevoerd, is de fout al opgetreden en is het resultaat doorgegeven aan andere formules. App.OnError regelt alleen hoe de fout aan de eindgebruiker wordt gerapporteerd en biedt de maker een haak om de fout indien gewenst te loggen.

De bereikvariabelen FirstError en AllErrors geven contextinformatie over de fout of fouten. Dit geeft informatie over het soort fout, waar de fout is ontstaan en waar deze is waargenomen.

Stoppen na een fout

Gedragsformules ondersteunen het ondernemen van actie, het aanpassen van databases en het veranderen van status. Met deze formules kunnen meerdere acties achter elkaar worden uitgevoerd met de ketenvormingsoperator ; (of ;; afhankelijk van de landinstellingen).

In dit geval laat het rasterbesturingselement bijvoorbeeld zien wat er in de T-tabel staat. Elke geselecteerde knop verandert de status in deze tabel met twee Patch-aanroepen:

Animatie waarin de twee records in tabel T worden bijgewerkt met willekeurige getallen na elke klik op de knop

In een keten met gedragsformules stoppen acties niet na de eerste fout. Laten we ons voorbeeld aanpassen om een ongeldig indexnummer door te geven in de eerste Patch-aanroep. De tweede Patch gaat door ondanks deze eerdere fout. De eerste fout wordt gerapporteerd aan de eindgebruiker en weergegeven als een fout in Studio op het besturingselement:

Animatie waarin alleen het tweede record in tabel T wordt bijgewerkt met willekeurige getallen na elke klik op de knop, het eerste record resulteert in een fout

IfError kan worden gebruikt om de uitvoering te stoppen na een fout. Net als bij de If-functie biedt het derde argument van deze functie een plaats om acties neer te zetten die alleen moeten worden uitgevoerd als er geen fout is:

Animatie die geen wijzigingen laat zien aan beide records in tabel T, omdat IfError verhindert dat de tweede bewerking wordt voltooid na een fout

Als er een fout wordt aangetroffen tijdens een van de iteraties van ForAll, stopt de rest van de iteraties niet. ForAll is ontworpen om elke iteratie onafhankelijk uit te voeren, waardoor parallelle uitvoering mogelijk is. Wanneer ForAll is voltooid, wordt een fout geretourneerd die alle gevonden fouten bevat (door te kijken naar AllErrors in IfError of App.OnError).

De volgende formule resulteert bijvoorbeeld in het retourneren door ForAll van twee fouten ( twee keer voor deling door nul voor Value van 0) en Collection heeft drie records (voor als Value niet 0 is): [1, 2, 3].

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

Werken met meerdere fouten

Aangezien een gedragsformule meer dan één actie kan uitvoeren, kunnen er ook meerdere fouten optreden.

Standaard wordt de eerste fout gemeld aan de eindgebruiker. In dit voorbeeld mislukken beide Patch-aanroepen, de tweede met een deling door nul-fout. Alleen de eerste fout (over index) wordt aan de gebruiker getoond:

Eerste indexfout weergegeven in een foutbanner, de tweede fout wordt niet gerapporteerd

De IfError-functie en App.OnError hebben toegang tot alle fouten die zijn opgetreden met de bereikvariabele AllErrors. In dit geval kunnen we dit instellen op een globale variabele en kijken naar beide aangetroffen fouten. Ze verschijnen in de tabel in dezelfde volgorde waarin ze zijn aangetroffen:

Leg de fouten vast in de globale variabele PatchErrors waar we kunnen zien dat beide fouten aanwezig zijn

Er kunnen ook meerdere fouten worden geretourneerd in niet-gedragsformules. Als u bijvoorbeeld de Patch-functie gebruikt met een batch met records die moeten worden bijgewerkt, kunnen meerdere fouten worden geretourneerd, één voor elke record die mislukt.

Fouten in tabellen

Zoals we eerder zagen, kunnen fouten worden opgeslagen in variabelen. Ook in gegevensstructuren, zoals tabellen, kunnen fouten worden opgenomen. Dit is belangrijk, omdat een fout in één record dan niet de hele tabel ongeldig kan maken.

Bekijk bijvoorbeeld dit gegevenstabelbesturingselement in Power Apps:

Gegevenstabel met een fout voor het veld Reciproque voor een invoer van 0, wat resulteert in een deling door nul-fout

De berekening in AddColumns heeft een deling door nul-fout aangetroffen voor een van de waarden. Voor die ene record heeft de kolom Reciproque een foutwaarde (deling door nul), maar de andere records zijn in orde. IsError( Index( output, 2 ) ) retourneert false en IsError( Index( output, 2 ).Value ) retourneert true.

Als er een fout optreedt bij het filteren van een tabel, is de hele record fout. De record wordt echter nog wel geretourneerd in het resultaat, zodat de eindgebruiker weet dat er iets was en dat er een probleem is.

Kijk naar dit voorbeeld. Hier bevat de oorspronkelijke tabel geen fouten, maar bij het filteren wordt een fout veroorzaakt wanneer Waarde gelijk is aan 0:

Gegevenstabel met fouten voor twee records die niet konden worden verwerkt door de filtercriteria

De waarden -5 en -3 worden correct uitgefilterd. De waarden 0 resulteren in een fout bij het verwerken van het filter, waardoor het onduidelijk is of de record al dan niet in het resultaat moet worden opgenomen. Om de transparantie voor eindgebruikers te maximaliseren en makers te helpen bij het opsporen van fouten, voegen we een foutrecord toe in plaats van het origineel. In dit geval geeft IsError( Index( output, 2 ) ) waar als resultaat.

Gegevensbronfouten

De functies die gegevens in gegevensbronnen wijzigen, zoals Patch, Collect, Remove, RemoveIf, Update, UpdateIf en SubmitForm rapporteren fouten op twee manieren:

  • Elk van deze functies retourneert een foutwaarde als resultaat van de bewerking. Fouten kunnen zoals gewoonlijk worden opgespoord met IsError en worden vervangen of onderdrukt met IfError en App.OnError.
  • Na de bewerking retourneert de functie Errors ook de fouten voor eerdere bewerkingen. Dit kan handig zijn om het foutbericht op een formulierscherm weer te geven zonder de fout in een statusvariabele te hoeven vastleggen.

Deze formule controleert bijvoorbeeld op een fout van Collect en geeft een aangepast foutbericht weer:

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

De functie Errors retourneert ook informatie over eerdere fouten tijdens runtime-bewerkingen. Dit kan handig zijn om een fout op een formulierscherm weer te geven zonder de fout in een statusvariabele te hoeven vastleggen.

Fouten opnieuw genereren

Soms worden potentiële fouten verwacht en kunnen ze veilig worden genegeerd. Als binnen IfError en App.OnError een fout wordt gedetecteerd die moet worden doorgegeven aan de volgende hogere handler, kan deze opnieuw worden gegenereerd met Error( AllErrors ).

Uw eigen fouten maken

U kunt ook uw eigen fouten maken met de functie Error.

Als u uw eigen fouten maakt, is het raadzaam waarden boven de 1000 te gebruiken om mogelijke conflicten met toekomstige systeemfoutwaarden te voorkomen.

Waarden ErrorKind-opsomming

ErrorKind-opsomming Waarde Beschrijving
AnalysisError 18 Systeemfout. Er was een probleem met de compileranalyse.
BadLanguageCode 14 Er is een ongeldige of niet-herkende taalcode gebruikt.
BadRegex 15 Ongeldige reguliere expressie. Controleer de gebruikte syntaxis met de functies IsMatch, Match of MatchAll.
Conflict 6 De record die wordt bijgewerkt, is al bij de bron gewijzigd en het conflict moet worden opgelost. Een gebruikelijke oplossing is om eventuele lokale wijzigingen op te slaan, de record te vernieuwen en de wijzigingen opnieuw toe te passen.
ConstraintViolated 8 De record is niet door een beperkingscontrole op de server gekomen.
CreatePermission 3 De gebruiker heeft geen toestemming om een record aan te maken voor de gegevensbron. De functie Collect is bijvoorbeeld aangeroepen.
DeletePermissions 5 De gebruiker heeft geen toestemming om een record te verwijderen voor de gegevensbron. De functie Remove is bijvoorbeeld aangeroepen.
Div0 13 Delen door nul.
EditPermissions 4 De gebruiker heeft geen toestemming om een record aan te maken voor de gegevensbron. De functie Patch is bijvoorbeeld aangeroepen.
GeneratedValue 9 Er is ten onrechte een waarde doorgegeven aan de server voor een veld dat automatisch door de server wordt berekend.
InvalidFunctionUsage 16 Ongeldig gebruik van een functie. Vaak zijn een of meer van de argumenten van de functie onjuist of op een ongeldige manier gebruikt.
FileNotFound 17 De opslag SaveData is niet gevonden.
InsufficientMemory 21 Het apparaat bevat onvoldoende geheugen of opslagruimte voor de bewerking.
InvalidArgument 25 Er is een ongeldig argument doorgegeven aan de functie.
Internal 26 Systeemfout. Er was een intern probleem met een van de functies.
MissingRequired 2 Een verplicht veld van een record ontbreekt.
Network 23 Er is een probleem opgetreden met de netwerkcommunicatie.
Geen 0 Systeemfout. Er is geen fout.
Niet toepasbaar 27 Er is geen waarde beschikbaar. Nuttig om onderscheid te maken tussen een lege waarde die kan worden behandeld als een nul in numerieke berekeningen en lege waarden die moeten worden gemarkeerd als een mogelijk probleem als de waarde wordt gebruikt.
NotFound 7 Record kan niet worden gevonden. Bijvoorbeeld de record die moet worden gewijzigd in de Patch-functie.
NotSupported 20 Bewerking wordt niet ondersteund door deze speler of dit apparaat.
Numeriek 24 Een numerieke functie wordt op een onjuiste manier gebruikt. Bijvoorbeeld: Sqrt met -1.
QuotaExceeded 22 Opslaglimiet overschreden.
ReadOnlyValue 10 Kolom is alleen-lezen en kan niet worden gewijzigd.
ReadPermission 19 De gebruiker heeft geen toestemming om een record te lezen voor de gegevensbron.
Sync 1 Er is een fout gerapporteerd door de gegevensbron. Controleer de kolom Bericht voor meer informatie.
Unknown 12 Er is een onbekend type fout opgetreden.
Validation 11 De record is niet geslaagd voor een validatiecontrole.