Feilbehandling
Merk
Funksjonaliteten som denne artikkelen beskriver, er bare tilgjengelig når forhåndsversjonsfunksjonen Feiladministrasjon på formelnivå i via Innstillinger>Kommende funksjoner>Forhåndsversjon er slått på. Mer informasjon: Kontrollere hvilke funksjoner som er aktivert
Feil skjer. Nettverk er nede, lagringsplassen blir full, uventede verdier flyter inn. Det er viktig at logikken fortsatt fungerer som den skal i møte med potensielle problemer.
Som standard flyter feil gjennom formlene i en app og rapporteres til sluttbrukeren av appen. På denne måten vet sluttbrukeren at noe uventet har skjedd, at de kan løse problemet selv med andre inndata, eller de kan rapportere problemet til eieren av appen.
Som apputvikler kan du ta kontroll over feil i appen:
- oppdage og håndtere en feil Hvis det er stor sannsynlighet for at det kan oppstå en feil, kan appens formler skrives for å registrere feilbetingelsen og prøve operasjonen på nytt. Sluttbrukeren trenger ikke bekymre seg for at det oppstod en feil fordi utvikleren tok muligheten i betraktning. Dette gjøres med funksjonene IfError, IsError og IsErrorOrBlank i en formel.
- rapportere en feil Hvis en feil ikke håndteres i formelen der den ble funnet, bobles feilen opp til behandleren App.OnError. Her kan ikke feilen lenger erstattes fordi den allerede har oppstått og er en del av formelberegninger. Du kan imidlertid bruke App.OnError til å styre hvordan feilen rapporteres til sluttbrukeren, inkludert å hindre feilrapportering samlet. App.OnError gir også et felles flaskehalspunkt for feilrapportering på tvers av hele appen.
- opprette og aktivere en feil på nytt Til slutt kan du oppdage en feilbetingelse med din egen logikk, en betingelse som er spesifikk for appen. Bruk Error-funksjonen til å opprette egendefinerte feil. Funksjonen Error brukes også til å skape en feil på nytt etter å ha blitt avhørt i IfError eller App.OnError.
Kom i gang
La oss starte med et enkelt eksempel.
- Opprett en ny skjerm i en Power Apps-lerretsapp.
- Sett inn en TextInput-kontroll. Den får standardnavnet TextInput1.
- Sett inn en Label-kontroll.
- Sett Text-egenskapen for Label-kontrollen til formelen
1/Value( TextInput1.Text )
Det har oppstått en feil fordi standardteksten i en TextInput-kontroll er "Text input"
, som ikke kan konverteres til et tall. Som standard er dette bra: sluttbrukeren får et varsel om at noe ikke fungerer som forventet i appen.
Vi ønsker ikke å gi brukeren en feil hver gang de starter denne appen. Sannsynligvis er ikke "Text input"
riktig standard for tekstinnskrivingsboksen likevel. Dette løses ved å endre Default-egenskapen i TextInput-kontrollen til:
Blank()
Hmm, nå har vi en annen feil. Matematiske operasjoner med tom, for eksempel divisjon, tvinger den tomme verdien til en null. Og det fører nå til en divisjon med null-feil. For å løse dette må vi avgjøre hva den riktige virkemåten er for denne situasjonen i denne appen. Svaret kan være å vise tom når tekstinnskriving er tom. Vi kan oppnå dette ved å pakke inn formelen med IfError-funksjonen:
IfError( 1/Value( TextInput1.Text ), Blank() )
Nå erstattes feilen med en gyldig verdi, og feilbanneret er borte. Men vi har kanskje tatt i, IfError vi bruker dekker alle feil, inkludert å skrive inn en ugyldig verdi, for eksempel "hello"
. Vi kan løse dette ved å justere IfError til å håndtere divisjonen med null-saken bare med og å skape alle andre feil på nytt:
IfError( 1/Value( TextInput1.Text ),
If( FirstError.Kind = ErrorKind.Div0, Blank(), Error( FirstError ) ) )
La oss derfor kjøre appen og prøve noen andre verdier.
Uten en verdi, som når appen startes, vises det ingen svar når standardverdien er tom, men det vises heller ingen feil når IfError erstatter divisjon med null-feilen.
Hvis vi skriver inn 4, får vi forventet resultat 0,25:
Og hvis vi skriver inn noe ulovlig, som hello
, vi få et feilbanner:
Dette er et enkelt innføringseksempel. Feilhåndtering kan utføres på mange forskjellige måter, avhengig av behovene i appen:
- I stedet for et feilbanner kunne vi vise "#Error" i label-kontrollen med formelen. Hvis du vil at erstatningstypene skal være kompatible med det første argumentet til IfError, må vi eksplisitt konvertere det numeriske resultatet til en tekststreng med Text-funksjonen.
IfError( Text( 1/Value( TextInput1.Text ) ), If( FirstError.Kind = ErrorKind.Div0, Blank(), "#Error" )
- I stedet for å bryte denne bestemte forekomsten med IfError kunne vi ha skrevet en sentralisert app.OnError-behandler. Vi kan ikke erstatte strengen som vises med "#Error", fordi feilen allerede har oppstått, og App.OnError gis bare for kontrollrapportering.
If( FirstError.Kind <> ErrorKind.Div0, Error( FirstError ) )
Feiloverføring
Feil flyter mye gjennom formler slik de gjør i Excel. Hvis cellen A1
for eksempel har formelen =1/0
i Excel, viser A1 feilverdien #DIV0!
:
Hvis cellen A2
henviser til A1
med en formel, for eksempel =A1*2
, overføres feilen også gjennom denne formelen:
Feilen erstatter verdien som ellers hadde blitt beregnet. Det er ikke noe resultat for multiplikasjon i cellen A2
, bare feilen fra divisjonen i A1
.
Power Fx fungerer på samme måte. Hvis en feil angis som et argument for en funksjon eller operator, vil operasjonen generelt sett ikke skje, og inndatafeilen strømmer gjennom som et resultat av operasjonen. Mid( Text( 1/0 ), 1, 1 )
vil for eksempel returnere en divisjon med null-feil fordi den indre feilen passerer gjennom Text-funksjonen og Mid-funksjonen:
Generelt flyter ikke feil gjennom Power Apps-kontrollegenskapene. La oss utvide det forrige eksemplet med en ekstra kontroll som vises hvis Text
-egenskapen for den første etiketten er en feiltilstand:
Det er greit at feil ikke overføres gjennom en kontroll, fordi systemet vil observere feil på inndataene til alle kontrollegenskapene. Feilen vil ikke gå tapt.
De fleste funksjoner og operatorer følger regelen "feil i feil ut", men det finnes noen unntak. Funksjonene IsError, IsErrorOrBlank og IfError er utformet for å arbeide med feil slik at de ikke kan returnere en feil selv om en slik sendes inn i dem.
Observere feil
Feil observeres ikke før verdien er brukt.
Derfor kan det hende at If- og Select-funksjonene ikke returnerer en feil hvis en slik sendes inn. Vurder formelen If( false, 1/0, 3 )
. Det finnes en divisjon med null-feil i denne formelen, men siden If
grenen ikke tar grenen på grunn av false
, rapporterer ikke Power Fx og Power Apps en feil:
Hvis du bruker Set-funksjonen med en feil, rapporteres det ikke en feil der feilen er plassert i variabelen. I Power Apps for eksempel her er en formel i App.OnStart som plasserer en divisjon med null-feil i variabelen x
:
Det rapporteres ingen feil fordi x
ikke henviser til noe. Men i det øyeblikket vi legger til en etikettkontroll og angir Text-egenskapen til x
, vises feilen:
Du kan observere feil i en formel med funksjonene IfError, IsError og IsErrorOrBlank. Med disse funksjonene kan du returnere en alternativ verdi, utføre alternativ handling eller endre feilen før den blir sett og rapportert.
Rapportere feil
Når en feil er overholdt, er neste trinn å rapportere feilen til sluttbrukeren.
I motsetning til Excel finnes det ikke alltid et praktisk sted for å vise et feilresultat, siden et resultat av en formel kan kjøre en egenskap, for eksempel X- og Y-koordinater for en kontroll, som det ikke er praktisk å vise tekst for. Hver Power Fx-vert styrer hvordan feil til slutt vises til sluttbrukeren, og hvor mye kontroll utvikleren har over denne prosessen. I Power Apps vises et feilbanner, og App.OnError brukes til å styre hvordan feilen rapporteres.
Det er viktig å merke seg at App.OnError ikke kan erstatte feilen på samme måte som IfError kan. Når App.OnError kjøres, har feilen allerede oppstått, og resultatet overføres gjennom andre formler. App.OnError kontrollerer bare hvordan feilen rapporteres til sluttbrukeren, og gir utvikleren en krok for å logge feilen hvis ønskelig.
Omfangsvariablene FirstError og AllErrors gir kontekstinformasjon om feilen eller feilene. Her finner du informasjon om hvilken type feil som oppstod og hvor feilen oppstod.
Stoppe etter en feil
Virkemåteformler støtter handling, endring av databaser og endring av tilstand. Disse formlene tillater at mer enn én handling kan utføres i en sekvens ved hjelp av ;
-sammenkjedingsoperatoren (eller ;;
avhengig av nasjonal innstilling).
I dette tilfellet viser for eksempel rutenettkontrollen hva som er i T
-tabellen. Hvert knappevalg endrer tilstanden i denne tabellen med to Patch-oppkall:
I en sammenkjedet funksjonalitetsformel stopper ikke handlinger etter den første feilen. La oss endre eksemplet slik at det sender et ugyldig indeksnummer i det første Patch-oppkallet. Den andre Patch fortsetter til tross for denne tidligere feilen. Den første feilen rapporteres til sluttbrukeren og vises som en feil i Studio på kontrollen:
IfError kan brukes til å stoppe kjøringen etter en feil. På samme måte som med If-funksjonen, er det tredje argumentet for denne funksjonen et sted der du bare kan plassere handlinger som skal utføres hvis det ikke oppstår feil:
Hvis det blir oppdaget en feil under en av iterasjonene av ForAll, vil ikke resten av iterasjonene stoppe. ForAll er designet for å utføre hver iterasjon uavhengig, noe som muliggjør parallell utførelse. Når ForAll er fullført, returneres det en feil som inneholder alle feilene som ble oppdaget (ved å undersøke AllErrors i IfError eller App.OnError).
Følgende formel vil for eksempel føre til at ForAll returnerer to feil (for divisjonen med null for Value
for 0, to ganger) og Collection
har tre oppføringer (for når Value
ikke er 0): [1, 2, 3]
.
Clear( Collection );
ForAll( [1,0,2,0,3], If( 1/Value > 0, Collect( Collection, Value ) ) );
Arbeid med flere feil
I og med at en funksjonalitetsformel kan kjøre mer enn én handling, kan det også oppstå mer enn én feil.
Som standard rapporteres den første feilen til sluttbrukeren. I dette eksemplet mislykkes begge Patch-oppkallene, den andre med en divisjon med null-feil. Bare den første feilen (om indeks) vises for brukeren:
IfError-funksjonen og App.OnError har tilgang til alle feilene som ble oppdaget med omfangsvariabelen AllErrors. I dette tilfellet kan vi angi en global variabel og se på begge feilene som ble oppdaget. De vises i tabellen i den samme rekkefølgen som de oppstod i:
Det kan også returneres flere feil i formler som ikke er i bruk. Hvis du for eksempel bruker Patch-funksjonen med en gruppe oppføringer som skal oppdateres, kan det returnere flere feil, én for hver oppføring som mislykkes.
Feil i tabeller
Som vi så tidligere, kan feil lagres i variabler. Feil kan også inkluderes i datastrukturer, for eksempel tabeller. Dette er viktig for at en feil i en oppføring ikke kan ugyldiggjøre hele tabellen.
Vurder for eksempel denne datatabellkontrollen i Power Apps:
Beregningen i AddColumns har støtt på en divisjon med null-feil for en av verdiene. For den ene oppføringen har den gjensidige kolonnen en feilverdi (divisjon med null), men de andre oppføringene har det ikke og har det bra. IsError( Index( output, 2 ) )
returnerer usann og IsError( Index( output, 2 ).Value )
returnerer sann.
Hvis det oppstår en feil under filtrering av en tabell, er hele oppføringen en feil, men den returneres likevel i resultatet slik at sluttbrukeren vet at noe var der, og at det er et problem.
Bruk dette eksempelet. Her oppstår det ingen feil i den opprinnelige tabellen, men filtreringshandlingen oppretter en feil når Verdien er lik 0:
Verdiene -5 og -3 er riktig filtrert ut. Verdiene 0 fører til en feil under behandling av filteret, og dermed er det viktig om oppføringen skal inkluderes eller ikke i resultatet. For å få størst mulig utbytte av feilsøking for sluttbrukere og hjelpe utviklere med feilsøking inkluderer vi en feiloppføring i stedet for den opprinnelige oppføringen. I dette tilfellet returnerer IsError( Index( output, 2 ) )
sann.
Datakildefeil
Funksjonene som endrer data i datakilder, som Patch, Collect, Remove, RemoveIf, Update, UpdateIf, and SubmitForm rapporterer feil på to måter:
- Hver av disse funksjonene returnerer en feilverdi som et resultat av operasjonen. Feil kan registreres med IsError og erstattes eller hindres med IfError og App.OnError som vanlig.
- Etter operasjonen returnerer Errors-funksjonen også feilene for tidligere operasjoner. Dette kan være nyttig for å vise feilmeldingen på skjemaskjermbildet uten at du trenger å registrere feilen i en tilstandsvariabel.
Denne formelen ser for eksempel etter en feil fra Collect og viser en egendefinert feilmelding:
IfError( Collect( Names, { Name: "duplicate" } ),
Notify( $"OOPS: { FirstError.Message }", NotificationType.Warning ) )
Errors-funksjonen returnerer også informasjon om tidligere feil under kjøretidsoperasjoner. Det kan være nyttig for å vise en feil på skjemaskjermbildet uten at du trenger å registrere feilen i en tilstandsvariabel.
Skape feil på nytt
Noen ganger forventes det noen potensielle feil og kan trygt ignoreres. Hvis det blir oppdaget en feil i IfError og App.OnError som skal sendes videre til neste høyere behandler, kan den sendes på nytt med Error( AllErrors )
.
Opprette dine egne feil
Du kan også opprette dine egne feil med Error-funksjonen.
Hvis du oppretter dine egne feil, anbefales det at du bruker verdier over 1000 for å unngå potensielle konflikter med fremtidige systemfeilverdier.
ErrorKind-opplistingsverdier
ErrorKind-opplisting | Verdi | Bekrivelse |
---|---|---|
AnalysisError | 18 | Systemfeil. Det oppstod et problem med kompileringsanalyse. |
BadLanguageCode | 14 | Det ble brukt en ugyldig eller ukjent språkkode. |
BadRegex | 15 | Ugyldig vanlig uttrykk. Kontroller syntaksen som brukes med funksjonene IsMatch, Match eller MatchAll. |
Konflikt | 6 | Oppføringen som oppdateres, er allerede endret i kilden, og konflikten må løses. En vanlig løsning er å lagre eventuelle lokale endringer, oppdatere oppføringen og bruke endringene på nytt. |
ConstraintViolated | 8 | Oppføringen bestod ikke en begrensningskontroll på serveren. |
CreatePermission | 3 | Brukeren må ikke opprette oppføringstillatelse for datakilden. Collect-funksjonen ble for eksempel oppkalt. |
DeletePermissions | Fem | Brukeren må ikke slette oppføringstillatelse for datakilden. Remove-funksjonen ble for eksempel oppkalt. |
Div0 | 13 | Deling med null. |
EditPermissions | 4 | Brukeren må ikke opprette oppføringstillatelse for datakilden. Patch-funksjonen ble for eksempel oppkalt. |
GeneratedValue | 9 | En verdi ble feilaktig sendt til serveren for et felt som automatisk beregnes av serveren. |
InvalidFunctionUsage | 16 | Ugyldig bruk av en funksjon. Ofte er et eller flere av argumentene for funksjonen feil eller brukt på en ugyldig måte. |
FileNotFound | 17 | SaveData-lagringen ble ikke funnet. |
InsufficientMemory | 21 | Ikke nok minne eller lagringsplass på enheten til operasjonen. |
InvalidArgument | 25 | Et ugyldig argument ble er sendt til en funksjon. |
Intern | 26 | Systemfeil. Det var et internt problem med en av funksjonene. |
MissingRequired | 2 | Et obligatorisk felt i en oppføring manglet. |
Nettverk | 23 | Det er et problem med nettverkskommunikasjoner. |
None | 0 | Systemfeil. Finner ingen feil. |
Ikke aktuelt | 27 | Ingen verdier er tilgjengelige. Nyttig for å skille en tom verdier som kan behandles som null i numeriske beregninger, fra tomme verdier som skal flagges som et mulig problem hvis verdien brukes. |
NotFound | 7 | Finner ikke oppføringen. Oppføringen som skal endres i Patch-funksjonen. |
NotSupported | 20 | Operasjonen støttes ikke av denne spilleren eller enheten. |
Numerisk | 24 | En numerisk funksjon ble brukt på en enkel måte. For eksempel Sqrt med -1. |
QuoteExceeded | 22 | Lagringskvoten er overskredet. |
ReadOnlyValue | 10 | Kolonnen er skrivebeskyttet og kan ikke endres. |
ReadPermission | 19 | Brukeren må ikke lese oppføringstillatelse for datakilden. |
Synkroniser | 1 | En feil ble rapportert av datakilden. Kontroller meldingskolonnen for mer informasjon. |
Ukjent | 12 | Det oppstod en feil, men av en ukjent type. |
Validering | 11 | Oppføringen bestod ikke en valideringssjekk. |