Dela via


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. Program.OnError tillhandahåller också en gemensam plats för felrapportering i hela programmet.
  • 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.

  1. Skapa en ny skärm i en Power Apps-arbetsyteapp.
  2. Infoga en TextInput-kontroll. Denna återgår till standardnamnet TextInput1.
  3. Infoga en Etikett-kontroll.
  4. Ställ in egenskapen Text för kontrollen Etikett som formeln
1/Value( TextInput1.Text )

Felbanderollen som visas med

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()

Felbanderollen visas med

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() )

Ingen felbanderoll visas, ett fel på grund av ett tomt värde har ersatts med ett tomt

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 ) ) )

Ingen felbanderoll visas, ett fel som specifikt beror på division med noll har ersatts med ett tomt ämne, annars uppstår ett nytt fel

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.

Inget svar visas och inget fel banderoll

Om vi skriver i en "4" får vi det förväntade resultatet 0,25:

0,25 visas och inget fel banderoll

Och om vi skriver något otillåtet, till exempel hello, får vi en felbanderoll:

inget värde visas och felbanderollen visas för att det inte går att konvertera

Detta är ett enkelt introduktionsexempel. Felhantering kan göras på många olika sätt, beroende på programmets behov:

  1. 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" )
    
    inget felbanderoll och #Error visas som resultatet
  2. 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!:

Excel-kalkylblad med A1=1/0 och #DIV/0! visas i cellen

Om cellen A2 refererar till A1 med en formel, till exempel =A1*2, överförs även felet genom den formeln:

Excel-kalkylblad med A2=A1*2 och #DIV/0! visas i cellen

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:

Felbanderoll som visar ogiltig åtgärd: division med noll

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:

Inga fel visas på kontrollen på den andra etiketten

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:

Ingen felbanderoll visas med If-funktionen i etiketten Textegenskap

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:

Ingen felbanderoll visas med Ange funktionsanrop i App.OnStart

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:

Felbanderoll som visas med etikettkontroll som refererar till variabeln x

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. Program.OnError kontrollerar bara hur felet rapporteras till slutanvändaren, samt tillhandahåller en "hook" där utvecklaren kan logga felet vid behov.

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:

En entisering som visar de två posterna i tabell T som uppdateras med slumptal efter varje knappklick

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:

En första post som endast visar den andra posten i tabell T som uppdateras med slumptal efter varje knappklick och den första posten resulterar i ett fel

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:

Animering visar inga ändringar av någon av posterna i tabell T, eftersom IfError hindrar den andra åtgärden från att slutföras efter ett fel

Om ett fel påträffas under en av upprepningarna av ForAll stoppas inte resten av upprepningarna. ForAll har utformats för att köra varje upprepning fristående, 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:

Det första indexfelet som visas i en felbanderoll, det andra felet rapporteras inte

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:

Samla felen i den globala variabeln PatchErrors där vi kan se att båda felen finns

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:

Datatabell som visar ett fel för fältet ömsesidig för en indata på 0, vilket resulterar i en division med noll fel

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 "falskt" och IsError( Index( output, 2 ).Value ) returnerar "sant".

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:

Datatabell med fel för två poster som inte kunde bearbetas med filtervillkoren

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.