Felhantering
Kommentar
Funktionen som beskrivs i den här artikeln är endast tillgänglig när förhandsversionen för felhantering på formelnivå via Inställningar>Kommande funktioner>Förhandsversion är påslagen. Mer information: Styra vilka funktioner som ska vara aktiverade
Fel inträffar. Nätverk stängs ner, lagringsutrymmet fylls på och oväntade värden strömmar in. Det är viktigt att logiken fortsätter att fungera även vid möjliga problem.
Som standard passerar felen ett programs formel och rapporteras till programmets slutanvändare. På så sätt vet slutanvändaren att något oväntat har hänt, och kan potentiellt lösa problemet själva med en annan indata eller rapportera problemet till ägaren av programmet.
Som programutvecklare kan du ta kontroll över fel i programmet:
- Upptäcka och åtgärda ett fel. Om det finns en risk för fel kan programmets formel skrivas för att identifiera felvillkoret och utföra åtgärden igen. Slutanvändaren behöver inte bekymra sig om att ett fel uppstått, detta eftersom tillverkaren tog hänsyn till möjligheten. Detta görs med funktionerna IfError, IsError och IsErrorOrBlank inom en formel.
- Rapportera ett fel. Om ett fel inte hanteras i den formel där det upptäcktes, kommer felet att skickas vidare uppåt till hanteraren Program.OnError. Här kan felet inte längre ersättas eftersom det redan har inträffat och ingår i formelberäkningarna. Men du kan använda Program.OnError för att kontrollera hur felet rapporteras till slutanvändaren, inklusive att stänga av felrapporteringen helt. App.OnError ger också en gemensam flaskhals för felrapportering i hela appen.
- Skapa och återutlösa ett fel. Slutligen kan du komma att upptäcka ett felvillkor med din egen logik, ett villkor som är specifikt för just ditt program. Använd funktionen Fel om du vill skapa anpassade fel. Funktionen Fel används också för att återutlösa ett fel som fastnat i IfError eller Program.OnError.
Kom igång
Låt oss börja med ett enkelt exempel.
- Skapa en ny skärm i en Power Apps-arbetsyteapp.
- Infoga en TextInput-kontroll. Denna återgår till standardnamnet TextInput1.
- Infoga en Etikett-kontroll.
- Ställ in egenskapen Text för kontrollen Etikett som formeln
1/Value( TextInput1.Text )
Ett fel uppstår eftersom standardtexten i en TextInput-kontroll är "Text input"
, som inte kan konverteras till ett tal. Som standard är detta något positivt: Slutanvändaren får en avisering om att något inte fungerar som förväntat i programmet.
Vi vill självklart inte att ett fel ska visas för användaren varje gång denne startar programmet. "Text input"
är antagligen ändå inte rätt standardvärde för textinmatningsrutan. För att åtgärda detta ska vi ändra egenskapen Standardvärde för kontrollen Textinmatning till:
Blank()
Hm, nu har ett annat fel dykt upp. Matematiska åtgärder med tomt, till exempel division, kommer att framtvinga en noll istället för det tomma värdet. Detta fel förorsakar nu ett fel på grund av delning med noll. För att åtgärda detta måste vi bestämma vilket det lämpliga beteendet är för denna situation i detta program. Svaret kan komma att visa tomt när textinmatningen är tomt. Detta kan vi göra genom att skrota formeln med funktionen IfError:
IfError( 1/Value( TextInput1.Text ), Blank() )
Nu ersätts felet med ett giltigt värde, och felbanderollen har tagits bort. Men vi kanske tagit i för mycket: Det IfError vi använde visade sig omfatta alla fel, inklusive att ange ett ogiltigt värde som till exempel "hello"
. Vi kan åtgärda detta genom att justera vårt IfError så att detta hanterar fallet med delning med noll endast med följande fel, och istället återutlösa alla andra fel:
IfError( 1/Value( TextInput1.Text ),
If( FirstError.Kind = ErrorKind.Div0, Blank(), Error( FirstError ) ) )
Då kör vi vårt program och testar några olika värden.
Utan ett värde – till exempel när programmet körs – visas inget svar eftersom standardvärdet är tomt, men dessutom visas inget fel eftersom IfError ersätter felet vid delning med noll.
Om vi skriver i en "4" får vi det förväntade resultatet 0,25:
Och om vi skriver något otillåtet, till exempel hello
, får vi en felbanderoll:
Detta är ett enkelt introduktionsexempel. Felhantering kan göras på många olika sätt, beroende på programmets behov:
- Istället för en felbanderoll kunde vi ha visat "#Error" i etikettkontrollen med formeln. För att se till att ersättningstyperna är kompatibla med det första argumentet för IfError måste vi uttryckligen konvertera det numeriska resultatet till en textsträng med funktionen Text.
IfError( Text( 1/Value( TextInput1.Text ) ), If( FirstError.Kind = ErrorKind.Div0, Blank(), "#Error" )
- Istället för att koppla denna specifika instans till IfError hade vi kunnat skiva en central Program.OnError-hanterare. Vi kan inte ersätta strängen som visas med "#Error" eftersom felet redan har inträffat och Program.OnError endast tillhandahålls för att kontrollera rapportering.
If( FirstError.Kind <> ErrorKind.Div0, Error( FirstError ) )
Felspridning
Fel passerar formler på samma sätt som i Excel. Om till exempel cellen A1
i Excel har formeln =1/0
kommer A1 att visa felvärdet #DIV0!
:
Om cellen A2
refererar till A1
med en formel, till exempel =A1*2
, överförs även felet genom den formeln:
Felet ersätter det värde som annars skulle ha beräknats. Det finns inget resultat för multipliceringen i cell A2
, bara felet från divisionen i A1
.
Power Fx fungerar på samma sätt. Om ett fel ges som argument till en funktion eller operator utförs inte åtgärden, och indatafelet passerar som ett resultat av åtgärden. Mid( Text( 1/0 ), 1, 1 )
returnerar till exempel ett fel av typen "Delning med noll", detta eftersom det innersta felet passerar funktionen Text och funktionen Mitt:
I allmänhet passerar fel inte genom Power Apps-kontrollegenskaperna. Vi ska nu utöka föregående exempel med en ytterligare kontroll som visas om den första etikettens Text
-egenskap är ett feltillstånd:
Det är okej att fel inte överförs via en kontroll, detta eftersom systemet observerar fel på indata till alla kontrollegenskaper. Felet går inte förlorat.
De flesta funktioner och operatorer följer regeln "fel in, fel ut", men det finns några undantag. Funktionerna IsError, IsErrorOrBlank samt IfError har utformats i syfte att fungera tillsammans med fel, varför de kanske inte returnerar ett fel ens om ett sådant passerar dem.
Felobservering
Fel observeras inte förrän värdet har använts.
Därför kan det hända att funktionerna Om och Välj inte heller returnerar ett fel om ett sådant ankommer. Notera formeln If( false, 1/0, 3 )
. Denna formel omfattar ett fall av "delning med noll", men eftersom If
inte tar denna väg på grund av false
komme Power Fx och Power Apps inte att rapportera något fel:
Om du använder funktionen Ange med ett fel, rapporteras inget fel när felet placeras i variabeln. I Power Apps finns till exempel en formel i Program.OnStart som placerar ett fel av typen "delning med noll" i variabeln x
:
Inget fel rapporteras eftersom x
inte refereras. Så fort vi lägger till en etikettkontroll och anger egenskapen Text som x
visas emellertid följande fel:
Du kan observera fel med en formel med funktionerna IfError, IsError samt IsErrorOrBlank. Med dessa funktioner kan du returnera ett alternativt värde, vidta alternativa åtgärder eller ändra felet innan det observeras och rapporteras.
Rapportera fel
När ett fel har observerats är nästa steg att rapportera felet till slutanvändaren.
Till skillnad från Excel finns det inte alltid någon lämplig plats för att visa ett felresultat, detta eftersom resultatet av en formel kan leda till att en egenskap såsom X- och Y-koordinater för en kontroll som saknar lämplig plats att visa text. Varje enskild Power Fx-värd kontrollerar hur fel slutligen visas för slutanvändaren, samt hur stor kontroll utvecklarne har över den här processen. I Power Apps visas en felbanderoll, och Program.OnEraren används för att kontrollera hur felet rapporteras.
Det är viktigt att notera att Program.OnError inte kan ersätta felet på samma sätt som IfError kan. Vid den tidpunkt då Program.OnError körs har felet redan inträffat, och resultatet har spridits genom andra formler. App.OnError styr bara hur felet rapporteras till slutanvändaren och ger en krok för tillverkaren att logga felet om så önskas.
Omfattningsvariablerna FirstError och AllErrors tillhandahåller sammanhangsinformation om felet eller felen. Detta ger information om typen av fel, var felet uppstod samt var det observerades.
Stoppa efter ett fel
Funktionsformlar stöder vidtagande av åtgärder, att ändra databaser samt att ändra tillstånd. Med hjälp av dessa formeler kan mer än en åtgärd utföras i en sekvens med hjälp av kedjekopplingsoperatorn ;
(eller ;;
, beroende på språk).
I det här fallet visar till exempel rutnätskontrollen vad som finns i tabellen T
. Varje knapptryckning förändrar statusen för denna tabell med två korrigeringsanrop:
I en länkad funktionsformel stoppas inte åtgärderna efter det första felet. Vi ska nu ändra vårt exempel så att ett ogiltigt indexnummer släpps fram i det första korrigeringsanropet. Den andra korrigeringen fortsätter trots det tidigare felet. Det första felet rapporteras till slutanvändaren och visas som ett fel i Studio på kontrollen:
IfError kan användas för att stoppa körningen efter ett fel. På samma sätt som funktionen If tillhandahåller det tredje argumentet för denna funktion en plats där åtgärder kan placeras som endast ska utföras om inga fel uppstår:
Om ett fel påträffas under en av upprepningarna av ForAll stoppas inte resten av upprepningarna. ForAll är utformat för att köra varje iteration oberoende av varandra, vilket möjliggör parallell körning. När ForAll har slutförts returneras ett fel som innehåller samtliga fel som upptäckts (genom att undersöka AllErrors i IfError eller Program.OnError).
Följande formel resulterar till exempel i att ForAll returnerar två fel (för divisionen med noll för Value
0, två gånger) och Collection
kommer att ha tre poster (för när Value
inte är 0): [1, 2, 3]
.
Clear( Collection );
ForAll( [1,0,2,0,3], If( 1/Value > 0, Collect( Collection, Value ) ) );
Arbeta med flera fel
Eftersom en funktionsformel kan utföra mer än en åtgärd, kan det också uppstå mer än ett fel.
Som standard rapporteras det första felet till slutanvändaren. I det här exemplet misslyckas båda programkorrigeringsanrop, det andra med ett fel från divisionen med noll. Endast det första felet (om index) visas för användaren:
Funktionen IfError och Program.OnError kan komma åt alla fel som påträffats med omfattningsvariabeln AllErrors. I det här fallet kan vi ange detta som en global variabel och titta på båda felen som påträffats. Dessa visas i tabellen i samma ordning som de påträffades:
Flera fel kan returneras även i icke-funktionsformler. Om du t.ex. använder korrigeringsfunktionen med en grupp poster som ska uppdateras kan detta returnera flera fel, ett för varje post som misslyckas.
Fel i tabeller
Som vi såg tidigare kan fel lagras i variabler. Fel kan också finnas i datastrukturer, till exempel tabeller. Detta är viktigt för att ett fel i en post inte ska kunna göra hela tabellen ogiltig.
Du kan till exempel använda denna datatabellkontrollen i Power Apps:
Beräkningen i AddColumns har påträffat ett fel med delning med noll för ett av värdena. För den posten har kolumnen Ömsesidig ett felvärde (delning med noll), men de andra posterna har inte detta fel, utan är korrekta. IsError( Index( output, 2 ) )
Returnerar false och IsError( Index( output, 2 ).Value )
returnerar true.
Om ett fel uppstår när en tabell filtreras är hela posten ett fel men returneras ändå i resultatet, detta så att slutanvändaren vet att något fanns där och att ett problem uppstått.
Använd detta exempel. Här visas inga fel i ursprungstabellen, men filtreringsåtgärden skapar ett fel närhelst Värde är lika med 0:
Värdena -5 och -3 filtreras ut korrekt. Värdena 0 resulterar i ett fel i bearbetningen av filtret. Därför är det oklart om posten ska tas med i resultatet eller inte. För att maximera transparensen för slutanvändare och hjälpa beslutsfattare att felsöka inkluderar vi en felpost i stället för ursprungsversionen. I detta fall returnerar IsError( Index( output, 2 ) )
"sant".
Datakällfel
Funktionerna som ändrar data i datakällor, till exempel Korrigering, Samla in, Ta bort, Ta bort Om, Uppdatera, Uppdatera Om samt Skicka in formulär rapporterar fel på två olika sätt:
- Var och en av dessa funktioner returnerar ett felvärde som ett resultat av åtgärden. Fel kan identifieras med IsError och ersättas eller IfError och Program.OnError.
- När åtgärden är över returnerar funktionen Fel även felen för tidigare åtgärder. Detta kan vara användbart om du vill visa felmeddelandet på formulärskärmen utan att behöva registrera felet i en tillståndsvariabel.
Med den här formeln visas exempelvis ett felmeddelande från Samla in och ett anpassat felmeddelande:
IfError( Collect( Names, { Name: "duplicate" } ),
Notify( $"OOPS: { FirstError.Message }", NotificationType.Warning ) )
Funktionen Fel returnerar även information om tidigare fel under körningsåtgärder. Detta kan vara användbart om du vill visa ett felmeddelande på en formulärskärm utan att behöva registrera felet i en tillståndsvariabel.
Återutlösa fel
Ibland kan vissa möjliga fel förväntas och ignoreras utan risk. Om ett fel hittas inuti IfError och Program.OnError som bör vidarebefordras till näste högre hanterare, kan detta återutlösas tillsammans med Error( AllErrors )
.
Skapa dina egna fel
Du kan också skapa dina egna fel med funktionen Fel.
Om du skapar dina egna fel bör du använda värden över 1 000 för att undvika eventuella konflikter med framtida systemfelvärden.
ErrorKind-uppräkningsvärden
ErrorKind-uppräkning | Värde | Description |
---|---|---|
AnalysisError | 18 | Systemfel. Ett problem uppstod med kompileraranalysen. |
BadLanguageCode | 14 | En ogiltig eller oregistrerad språkkod användes. |
BadRegex | 15 | Ogiltigt reguljärt uttryck. Kontrollera syntaxen som används med funktionerna IsMatch, Match eller MatchAll. |
Konflikt | 6 | Posten som uppdateras har redan ändrats vid källan och konflikten måste lösas. En vanlig lösning är att spara eventuella lokala ändringar, uppdatera posten och sedan återtillämpa ändringarna. |
ConstraintViolated | 8 | Posten skickade ingen begränsningskontroll på servern. |
CreatePermission | 3 | Användaren har inte behörighet att skapa poster för datakällan. Exempelvis anropades funktionen Samla in. |
DeletePermissions | 5 | Användaren har inte behörighet att ta bort poster för datakällan. Exempelvis anropades funktionen Ta bort. |
Div0 | 13 | Delning med noll. |
EditPermissions | 4 | Användaren har inte behörighet att skapa poster för datakällan. Exempelvis anropades funktionen Korrigering. |
GeneratedValue | 9 | Ett värde skickades till felaktigt till servern för ett fält som beräknas automatiskt av servern. |
InvalidFunctionUsage | 16 | Ogiltig funktionsanvändning. Ofta är ett eller flera av argumenten till funktionen felaktiga eller används på ett ogiltigt sätt. |
FileNotFound | 17 | Minnet för SaveData kunde inte hittas. |
InsufficientMemory | 21 | Det finns inte tillräckligt med minne eller lagringsutrymme på enheten för åtgärden. |
InvalidArgument | 25 | Ett ogiltigt argument skickades till en funktion. |
Internt | 26 | Systemfel. Det uppstod ett internt problem med en av funktionerna. |
MissingRequired | 2 | Ett obligatoriskt fält för en post saknades. |
Nätverk | 23 | Det har uppstått ett problem med nätverkskommunikationerna. |
Inga | 0 | Systemfel. Det finns inga fel. |
Gäller inte | 27 | Det finns inga värden. Detta är praktiskt om du vill särskilja ett tomt värde som kan behandlas som noll i numeriska beräkningar från tomma värden som ska betraktas som ett potentiellt problem om värdet används. |
NotFound | 7 | Det gick inte att hitta posten. Till exempel posten som ska ändras i funktionen Korrigering. |
NotSupported | 20 | Åtgärden stöds inte av denna spelare eller enhet. |
Numerisk | 24 | En numerisk funktion användes på ett felaktigt sätt. Till exempel Sqrt med -1. |
QuoteExceeded | 22 | Lagringskvoten överskreds. |
ReadOnlyValue | 10 | Kolumnen är skrivskyddad och kan inte ändras. |
ReadPermission | 19 | Användaren har inte läsbehörighet för datakällans poster. |
Synkronisera | 1 | Ett fel rapporterades av datakällan. Kontrollera meddelandekolumnen för mer information. |
Okänd | 12 | Det uppstod ett fel, men av ett okänt slag. |
Verifiering | 11 | Posten har inte klarat en valideringskontroll. |