Partajați prin


Eroare de tratare

Notă

Comportamentul pe care îl descrie acest articol este disponibil numai atunci când caracteristica experimentală Gestionarea erorilor la nivel de formulă din Setări>Caracteristici ulterioare>Previzualizare este activată. Mai multe informații: Controlarea caracteristicilor care sunt activate

Se întâmplă erori. Rețelele se defectează, stocarea se umple, valorile neașteptate apar. Este important ca logica dvs. să continue să funcționeze corect în fața potențialelor probleme.

În mod implicit, erorile apar prin formulele unei aplicații și sunt raportate utilizatorului final al aplicației. În acest fel, utilizatorul final știe că s-a întâmplat ceva neașteptat, poate rezolva singur problema cu o altă intrare sau poate raporta problema proprietarului aplicației.

În calitate de producător de aplicații, puteți prelua controlul asupra erorilor din aplicația dvs.:

  • Detectarea și gestionarea unei erori. Dacă există șansa să apară o eroare, formulele aplicației pot fi scrise pentru a detecta starea de eroare și a reîncerca operația. Utilizatorul final nu trebuie să fie îngrijorat că a apărut o eroare, deoarece producătorul a luat în considerare această posibilitate. Se face cu funcțiile IfError, IsError, and IsErrorOrBlank într-o formulă.
  • Raportarea unei erori. Dacă o eroare nu este gestionată în formula în care a fost întâlnită, eroarea este apoi transmisă la rutina de tratare App.OnError. Aici, eroarea nu mai poate fi înlocuită, deoarece a apărut deja și face parte din calculele formulei. Dar puteți utiliza App.OnError pentru a controla modul în care eroarea este raportată utilizatorului final, inclusiv pentru a suprima raportarea erorilor. App.OnError oferă, de asemenea, un punct de sufocare comun pentru raportarea erorilor în întreaga aplicație..
  • Crearea și reintroducerea unei erori. În cele din urmă, este posibil să detectați o condiție de eroare cu propria logică, o condiție care este specifică aplicației dvs. Utilizați funcția Eroare pentru a crea erori personalizate. Funcția Eroare este, de asemenea, utilizată pentru a reintroduce o eroare după ce a fost interogată în IfError sau App.OnError.

Introducere

Să începem cu un exemplu simplu.

  1. Creați un ecran nou în aplicația Planșă de lucru Power Apps.
  2. Inserați un control TextInput. Va avea implicit numele TextInput1.
  3. Introduceți un control Etichetă.
  4. Setați proprietatea Text a acestui controlului Etichetă la formulă
1/Value( TextInput1.Text )

Banner de eroare afișat cu „Valoarea nu poate fi convertită într -un număr” pentru controlul de intrare text care conține „Intrare text”

Avem o eroare deoarece textul implicit al unui control TextInput este "Text input", care nu poate fi convertit într-un număr. În mod implicit, acesta este un lucru bun: utilizatorul final va primi o notificare că ceva nu funcționează conform așteptărilor în aplicație.

Evident, nu dorim ca o eroare să întâmpine utilizatorul de fiecare dată când pornește această aplicație. Probabil că "Text input" nu este valoarea implicită potrivită pentru caseta de introducere a textului. Pentru a remedia acest lucru, să modificăm proprietatea Implicit a controlului TextInput la:

Blank()

Banner de eroare afișat cu „diviziunea la zero”

Hmm, acum avem o altă eroare. Operațiile matematice cu gol, cum ar fi împărțirea, vor forța valoarea goală la zero. Și asta provoacă acum o eroare de împărțire la zero. Pentru a remedia acest lucru, trebuie să decidem care este comportamentul potrivit pentru această situație în această aplicație. Răspunsul poate fi să arate gol când textul introdus este gol. Putem realiza acest lucru prin încheierea formulei noastre cu funcția IfError:

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

Nu este afișat niciun banner de eroare, o eroare datorată unei valori necompletate a fost înlocuită cu un necomplet

Acum eroarea este înlocuită cu o valoare validă și bannerul de eroare a dispărut. Dar, este posibil să fi depășit, IfErrorpe care l-am folosit acoperă toate erorile, inclusiv introducerea unei valori greșite, cum ar fi ca "hello". Putem rezolva acest lucru prin reglarea IfError pentru a gestiona împărțirea cu majuscule și minuscule numai cu și rearuncând toate celelalte erori:

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

Nu este afișat niciun banner de eroare, o eroare datorată în mod special împărțirii la zero a fost înlocuită cu un gol, în caz contrar eroarea este re-arunsă

Deci, să rulăm aplicația noastră și să încercăm câteva valori diferite.

Fără nicio valoare, ca atunci când pornește aplicația, nu este afișat niciun răspuns, deoarece valoarea implicită este gol, dar nicio eroare nu este afișată ca IfError înlocuiește împărțirea cu eroarea zero.

Niciun răspuns afișat și niciun banner de eroare

Dacă introducem un 4, obținem rezultatul așteptat de 0,25:

0.25 afișat și niciun banner de eroare

Și dacă introducem ceva ilegal, cum ar fi hello, atunci vom primi un banner de eroare:

Nu este afișată nicio valoare și este afișat un banner de eroare pentru incapacitatea de a converti „bună ziua” într-un număr

Acesta este un exemplu introductiv simplu. Gestionarea erorilor se poate face în mai multe moduri diferite, în funcție de nevoile aplicației:

  1. În loc de un banner de eroare, am fi putut afișa „#Error” în controlul etichetei cu formula. Pentru a păstra tipurile de înlocuiri compatibile cu primul argument pentru IfError trebuie să transformăm în mod explicit rezultatul numeric într-un șir de text cu funcția Text.
    IfError( Text( 1/Value( TextInput1.Text ) ), 
             If( FirstError.Kind = ErrorKind.Div0, Blank(), "#Error" )
    
    Nici un banner de eroare și în schimb #Error este afișat ca rezultat
  2. În loc să încapsulăm această instanță specifică cu IfError am fi putut scrie o rutină de tratare centralizată App.OnError. Nu putem înlocui șirul afișat cu „#Error”, deoarece eroarea s-a produs deja și App.OnError este furnizată numai pentru a controla raportarea.
    If( FirstError.Kind <> ErrorKind.Div0, Error( FirstError ) )
    

Propagare eroare

Erorile curg prin formule la fel ca în Excel. De exemplu, în Excel, dacă celula A1 are formula =1/0 , atunci A1 va afișa valoarea de eroare #DIV0!:

Foaie de calcul Excel cu A1 = 1/0 și #div/0! arătat în celulă

Dacă celula A2 se referă la A1 cu o formulă precum =A1*2, atunci eroarea se propagă și prin această formulă:

Foaie de calcul Excel cu A2=A1*2 și #DIV/0! arătat în celulă

Eroarea înlocuiește valoarea care altfel ar fi fost calculată. Nu există niciun rezultat pentru înmulțirea în celula A2, doar eroarea de la împărțirea în A1.

Power Fx functioneaza la fel. În general, dacă o eroare este furnizată ca argument pentru o funcție sau operator, operația nu va avea loc și eroarea de intrare va curge ca rezultat al operației. De examplu, Mid( Text( 1/0 ), 1, 1 ) va returna o eroare Diviziune la zero, deoarece cea mai interioară eroare trece prin funcția Text și funcția Mid:

Banner de eroare care arată o operație nevalidă: împărțire la zero

În general, erorile nu trec prin proprietățile de control Power Apps. Să extindem exemplul anterior cu un control suplimentar care afișează dacă proprietatea Text a primei etichete este o stare de eroare:

Nu este afișată nicio eroare pe a doua etichetă de control

Este bine ca erorile să nu se propage printr-un control, deoarece sistemul va observa erori la intrarea tuturor proprietăților controlului. Eroarea nu se va pierde.

Majoritatea funcțiilor și operatorilor respectă regula „eroare de intrare, eroare de ieșire”, dar există câteva excepții. Funcțiile IsError, IsErrorOrBlank și IfError sunt concepute pentru a lucra cu erori, astfel încât să nu returneze o eroare chiar dacă una le este transmisă.

Observarea erorilor

Erorile nu sunt observate până când valoarea lor este utilizată.

Drept urmare, funcțiile If și Select ar putea să nu returneze o eroare dacă este transmisă una. Luați în considerare prima formulă If( false, 1/0, 3 ). Există o eroare de împărțire la zero prezentă în această formulă, dar din moment ce If nu ia acea ramură din cauza false, Power Fx și Power Apps nu va raporta o eroare:

Niciun banner de eroare afișat cu funcția If în proprietatea Text etichetă

Utilizarea funcției Setare cu o eroare nu va raporta o eroare în momentul în care eroarea este plasată în variabilă. De exemplu, în Power Apps, iată o formulă în App.OnStart care plasează o eroare de împărțire la zero în variabila x:

Nu este afișat niciun banner de eroare cu Setați apelul funcției în App.OnStart

Nu este raportată nicio eroare, deoarece x nu se face referire. Cu toate acestea, în momentul în care adăugăm un control etichetă și îi setăm Text proprietatea la x, eroarea este afișată:

Banner de eroare afișat cu controlul etichetei care face referire la variabila x

Puteți observa erorile dintr-o formulă cu funcțiile IfError, IsError și IsErrorOrBlank. Cu aceste funcții, puteți returna o valoare alternativă, puteți efectua acțiuni alternative sau puteți modifica eroarea înainte ca aceasta să fie observată și raportată.

Erori de raportare

După ce se observă o eroare, următorul pas este raportarea erorii utilizatorului final.

Spre deosebire de Excel, nu există întotdeauna un loc convenabil pentru a afișa un rezultat de eroare, deoarece rezultatul unei formule poate conduce la o proprietate precum coordonatele X și Y ale unui control pentru care nu există un loc convenabil pentru a afișa text. Fiecare gazdă Power Fx controlează modul în care erorile sunt afișate în cele din urmă utilizatorului final și cât de mult control are producătorul asupra acestui proces. În Power Apps, este afișat un banner de eroare și App.OnError este utilizat pentru a controla modul în care este raportată eroarea.

Este important să rețineți că App.OnError nu poate înlocui eroarea în același mod în care o poate înlocui IfError . În momentul în care App.OnError este executat, eroarea s-a produs deja, iar rezultatul s-a propagat prin alte formule. App.OnError controlează doar modul în care eroarea este raportată utilizatorului final și oferă un cârlig pentru ca producătorul să înregistreze eroarea, dacă dorește.

Variabilele de domeniu FirstError și AllErrors furnizează informații de context despre eroare sau erori. Acesta oferă informații despre tipul de eroare și unde a apărut eroarea și unde a fost observată.

Oprirea după o eroare

Formulele de comportament acceptă luarea de măsuri, modificarea bazelor de date și schimbarea stării. Aceste formule permit realizarea mai multor acțiuni într-o secvență folosind operatorul de înlănțuire ; (sau ;; în funcție de local).

În acest caz, de exemplu, controlul grilă arată ceea ce este în tabelul T. Fiecare buton selectat schimbă starea din acest tabel cu două apeluri Corecție:

Animație care arată cele două înregistrări din tabelul T fiind actualizate cu numere aleatorii după fiecare clic pe buton

Într-o formulă de comportament înlănțuit, acțiunile nu se opresc după prima eroare. Să modificăm exemplul nostru pentru a transmite un număr de index nevalid în primul apel Corecție . A doua Corecție continuă în ciuda acestei erori anterioare. Prima eroare este raportată utilizatorului final și afișată ca eroare în Studio pe control:

Animație care arată doar a doua înregistrare din tabelul T fiind actualizată cu numere aleatorii după fiecare clic pe buton, prima înregistrare ducând la o eroare

IfError poate fi folosit pentru a opri execuția după o eroare. Similar cu funcția If, al treilea argument al acestei funcție oferă un loc pentru a pune acțiuni care ar trebui să fie executate numai dacă nu există nicio eroare:

Animație care nu arată modificări la nicio înregistrare din tabelul T, deoarece IfError împiedică finalizarea celei de-a doua operațiuni după o eroare

Dacă se întâlnește o eroare în timpul uneia dintre iterațiile ForAll, restul iterațiilor nu se vor opri. ForAll este proiectat să execute fiecare iterație în mod independent, permițând execuția paralelă. Când ForAll este completă, va fi returnată o eroare, care conține toate erorile întâlnite (prin examinarea AllErrors în IfError sau App.OnError).

De exemplu, următoarea formulă va avea ca rezultat ForAll returnarea a două erori (pentru împărțirea la zero pentru Value de 0, de două ori) și Collection va avea trei înregistrări (pentru când Value nu este 0): [1, 2, 3].

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

Lucrul cu mai multe erori

Deoarece o formulă de comportament poate executa mai multe acțiuni, poate întâmpina și mai multe erori.

În mod implicit, prima eroare este raportată utilizatorului final. În acest exemplu, ambele apeluri Corecție vor eșua, al doilea cu o eroare de împărțire la zero. Numai prima eroare (despre index) este afișată utilizatorului:

Prima eroare de index este afișată într-un banner de eroare, a doua eroare nu este raportată

Funcția IfError și App.OnError pot accesa toate erorile întâlnite cu variabila de domeniu AllErrors. În acest caz, putem seta aceasta la o variabilă globală și ne uităm la ambele erori întâlnite. Ele apar în tabel în aceeași ordine în care au fost întâlnite:

Capturarea erorilor în variabila globală PatchErrors unde putem vedea că ambele erori sunt prezente

Mai multe erori pot fi returnate și în formulele non-comportament. De exemplu, utilizarea funcției Correcție cu un lot de înregistrări pentru actualizare poate returna mai multe erori, câte una pentru fiecare înregistrare care eșuează.

Erori în tabele

După cum am văzut mai devreme, erorile pot fi stocate în variabile. Erorile pot fi incluse și în structurile de date, cum ar fi tabele. Acest lucru este important pentru ca o eroare pe orice înregistrare să nu poată invalida întregul tabel.

De exemplu, luați în considerare acest control tabel de date în Power Apps:

Tabel de date care arată o eroare pentru câmpul Reciproc pentru o intrare de 0, care are ca rezultat o eroare de împărțire la zero

Calculul din AddColumns a întâmpinat o eroare de împărțire la zero pentru una dintre valori. Pentru acea înregistrare, coloana Reciprocă are o valoare de eroare (împărțire cu zero), dar celelalte înregistrări nu și sunt în regulă. IsError( Index( output, 2 ) ) returnează fals și IsError( Index( output, 2 ).Value ) returnează adevărat.

Dacă apare o eroare la filtrarea unui tabel, întreaga înregistrare este o eroare, dar totuși returnată în rezultat, astfel încât utilizatorul final să știe că a existat ceva și că există o problemă.

Utilizați acest exemplu. Aici, tabelul original nu are erori, dar actul de filtrare creează o eroare ori de câte ori Valoarea este egală cu 0:

Tabel de date care arată erori pentru două înregistrări care nu au putut fi procesate de criteriile de filtrare

Valorile -5 și -3 sunt filtrate corect. Valorile 0 au ca rezultat o eroare la procesarea filtrului și, prin urmare, nu este clar dacă înregistrarea ar trebui inclusă sau nu în rezultat. Pentru a maximiza transparența pentru utilizatorii finali și pentru a ajuta producătorii să depaneze, includem o înregistrare a erorilor în locul celui original. În acest caz, IsError( Index( output, 2 ) ) returnează adevărat.

Erori de sursă de date

Funcțiile care modifică sursele de date, ca Corecție, Colectare, Înlăturare, RemoveIf, Actualizare, UpdateIf și SubmitForm raportează erori în două moduri:

  • Fiecare dintre aceste funcții va returna o valoare de eroare ca rezultat al operației. Erorile pot fi detectate cu IsError și înlocuite sau suprimate cu IfError și App.OnError ca de obicei.
  • După operație, funcția Erori va returna și erorile pentru operațiunile anterioare. Poate fi util pentru afișarea ununi mesaj de eroarei pe un ecran de formular fără a fi nevoie să capturați eroarea într-o variabilă de stare.

De exemplu, această formulă va verifica dacă există o eroare de la Collect și va afișa un mesaj de eroare personalizat:

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

Funcția Erori returnează și informații despre erorile anterioare în timpul operațiunilor de rulare. Poate fi util pentru afișarea unei erori pe un ecran de formular fără a fi nevoie să capturați eroarea într-o variabilă de stare.

Erori de reintroducere

Uneori sunt așteptate unele erori potențiale și pot fi ignorate în siguranță. În interiorul IfError și App.OnError, dacă este detectată o eroare care ar trebui transmisă următoarei rutine de tratare superioare, poate fi aruncată din nou cu Error( AllErrors ).

Crearea propriilor erori

De asemenea, puteți crea propriile erori cu funcția Eroare.

Dacă vă creați propriile erori, este recomandat să utilizați valori peste 1000 pentru a evita potențialele conflicte cu valorile viitoare ale erorilor de sistem.

Valori de enumerare ErrorKind

Enumerare ErrorKind Valoare Descriere
AnalysisError 18 Eroare de sistem. A existat o problemă cu analiza compilatorului.
BadLanguageCode 14 A fost folosit un cod de limbă nevalid sau nerecunoscut.
BadRegex 15 Expresie regulată nevalidă. Verificați sintaxa folosită cu funcțiile IsMatch, Match sau MatchAll.
Conflict 6 Înregistrarea în curs de actualizare a fost deja modificată la sursă și conflictul trebuie rezolvat. O soluție comună este să salvați orice modificări locale, să reîmprospătați înregistrarea și să aplicați din nou modificările.
ConstraintViolated 8 Înregistrarea nu a trecut o verificare a constrângerii pe server.
CreatePermission 3 Utilizatorul nu are permisiunea de a crea înregistrări pentru sursa de date. De exemplu, a fost apelată funcția Colectare.
DeletePermissions 5 Utilizatorul nu are permisiunea de a șterge înregistrări pentru sursa de date. De exemplu, a fost apelată funcția înlăturare.
Div0 13 Împărțire la zero.
EditPermissions 4 Utilizatorul nu are permisiunea de a crea înregistrări pentru sursa de date. De exemplu, a fost apelată funcția Colecție.
GeneratedValue 9 O valoare a fost transmisă în mod eronat serverului pentru un câmp care este calculat automat de server.
InvalidFunctionUsage 16 Utilizarea nevalidă a unei funcții. Adesea, unul sau mai multe dintre argumentele funcției sunt incorecte sau utilizate într-un mod nevalid.
FileNotFound 17 Stocarea SaveData nu a putut fi găsită.
InsufficientMemory 21 Nu există suficientă memorie sau spațiu de stocare pe dispozitiv pentru operație.
InvalidArgument 25 Un argument nevalid a fost transmis unei funcții.
Internă 26 Eroare de sistem. A existat o problemă internă cu una dintre funcții.
MissingRequired 2 Un câmp obligatoriu al unei înregistrări lipsește.
Rețea 23 A existat o problemă cu comunicările de rețea.
Fără 0 Eroare de sistem. Nu există nicio eroare.
Inaplicabil 27 Nu sunt valori disponibile. Util pentru a diferenția o valoare gol care poate fi tratată ca zero în calculele numerice de valorile goale care ar trebui semnalate ca o problemă potențială dacă se utilizează valoarea.
NotFound 7 Înregistrarea nu s-a găsit. De exemplu, înregistrarea care urmează să fie modificată în funcția Corecție.
NotSupported 20 Operațiune neacceptată de acest player sau dispozitiv.
Numeric 24 O funcție numerică a fost folosită într-un mod impropriu. De examplue, Sqrt cu -1.
QuoteExceeded 22 Cotă de stocare depășită.
ReadOnlyValue 10 Coloana este numai pentru citire și nu poate fi modificată.
ReadPermission 19 Utilizatorul nu are permisiunea de a citi înregistrări pentru sursa de date.
Sincronizați 1 Sursă de date a raportat o eroare. Pentru mai multe informații verificați coloana Mesaje.
Necunoscut 12 A existat o eroare, dar de un tip necunoscut.
Validare 11 Înregistrarea nu a trecut un control de validare.