Gestion des erreurs
Remarque
Le comportement décrit dans cet article n’est disponible que lorsque la fonctionnalité de version préliminaire Gestion des erreurs au niveau de la formule dans Paramètres>Fonctionnalités à venir>Version préliminaire est activée. Pour plus d’informations, voir : Contrôle des fonctionnalités activées
Les erreurs arrivent. Les réseaux tombent en panne, le stockage se remplit, des valeurs inattendues affluent. Il est important que votre logique continue à fonctionner correctement face à des problèmes potentiels.
Par défaut, les erreurs passent par les formules d’une application et sont signalées à l’utilisateur final de l’application. Ainsi, l’utilisateur final sait que quelque chose d’inattendu s’est produit, il peut éventuellement résoudre le problème lui-même avec une autre entrée, ou il peut signaler le problème au propriétaire de l’application.
En tant que créateur d’applications, vous pouvez contrôler les erreurs dans votre application :
- Détection et traitement d’une erreur. Si une erreur risque de se produire, les formules de l’application peuvent être écrites de manière à détecter la condition d’erreur et à lancer une nouvelle tentative d’opération. L’utilisateur final n’a pas à s’inquiéter qu’une erreur survienne, car le créateur a tenu compte de cette possibilité. C’est possible grâce aux fonctions IfError, IsError et IsErrorOrBlank dans une formule.
- Signalement d’une erreur. Si une erreur n’est pas traitée dans la formule où elle est survenue, l’erreur est alors remontée vers le gestionnaire App.OnError. Ici, l’erreur ne peut plus être remplacée car elle s’est déjà produite et fait partie des calculs de la formule. Mais vous pouvez utiliser App.OnError pour contrôler la façon dont l’erreur est signalée à l’utilisateur final, y compris la suppression totale du signalement des erreurs. App.OnError fournit également un choke commun pointer pour la création de rapports d’erreurs dans l’ensemble de l’application.
- Création et relance d’une erreur. Enfin, vous pouvez détecter une condition d’erreur avec votre propre logique, une condition qui est spécifique à votre application. Utilisez la fonction Error pour créer et signaler des erreurs personnalisées. La fonction Error permet également de renvoyer une erreur après avoir été interrogée dans IfError ou App.OnError.
Démarrage
Commençons par un exemple simple.
- Créez un écran dans une application de canevas Power Apps.
- Insérez un contrôle TextInput. Par défaut, il portera le nom de TextInput1.
- Insérez un contrôle Label.
- Définissez la propriété Text du contrôle Label sur la formule
1/Value( TextInput1.Text )
Nous obtenons une erreur car le texte par défaut d’un contrôle TextInput est "Text input"
, qui ne peut pas être converti en nombre. Par défaut, c’est une bonne chose : l’utilisateur final recevra une notification lui indiquant que quelque chose ne fonctionne pas comme prévu dans l’application.
Évidemment, nous ne voulons pas que l’utilisateur soit accueilli par une erreur à chaque fois qu’il lance cette application. "Text input"
n’est probablement pas la bonne valeur par défaut pour la zone de saisie de texte. Pour remédier à cela, modifions la propriété Default du contrôle TextInput en :
Blank()
Hmm, à présent nous avons une erreur différente. Les opérations mathématiques avec des valeurs vides, telles que la division, contraindront la valeur vide à zéro. Et cela provoque maintenant une erreur de division par zéro. Pour y remédier, nous devons décider quel est le comportement approprié pour cette situation dans cette application. La réponse peut être d’afficher vide lorsque la saisie de texte est vide. Nous pouvons accomplir cela en enveloppant notre formule avec la fonction IfError :
IfError( 1/Value( TextInput1.Text ), Blank() )
À présent, l’erreur est remplacée par une valeur valide et la bannière d’erreur a disparu. Mais nous en avons peut-être trop fait : la fonction IfError que nous avons utilisée couvre toutes les erreurs, y compris la saisie d’une mauvaise valeur telle que "hello"
. Nous pouvons résoudre ce problème en ajustant notre fonction IfError pour ne traiter que le cas de la division par zéro et rejeter toutes les autres erreurs :
IfError( 1/Value( TextInput1.Text ),
If( FirstError.Kind = ErrorKind.Div0, Blank(), Error( FirstError ) ) )
Exécutons donc notre application et testons différentes valeurs.
Sans valeur, comme au démarrage de l’appli, il n’y a pas de réponse affichée car la valeur par défaut est vide, mais il n’y a pas non plus d’erreur affichée car la fonction IfError remplace l’erreur de division par zéro.
Si nous saisissons un 4, nous obtenons le résultat attendu de 0,25 :
Et si nous saisissons quelque chose d’illégal, comme hello
, nous obtenons une bannière d’erreur :
Il s’agit d’un exemple d’introduction simple. La gestion des erreurs peut se faire de différentes manières, en fonction des besoins de l’application :
- Au lieu d’une bannière d’erreur, nous aurions pu afficher "#Error" dans le contrôle d’étiquette avec la formule. Pour garder les types des remplacements compatibles avec le premier argument de la fonction IfError nous devons convertir explicitement le résultat numérique en une chaîne de texte à l’aide de la fonction Text.
IfError( Text( 1/Value( TextInput1.Text ) ), If( FirstError.Kind = ErrorKind.Div0, Blank(), "#Error" )
- Au lieu d’envelopper cette instance spécifique avec la fonction IfError nous aurions pu écrire un gestionnaire App.OnError centralisé. Nous ne pouvons pas remplacer la chaîne affichée par "#Error" car l’erreur s’est déjà produite et la fonction App.OnError est uniquement fournie pour contrôler les rapports.
If( FirstError.Kind <> ErrorKind.Div0, Error( FirstError ) )
Propagation des erreurs
Les erreurs circulent dans les formules comme elles le font dans Excel. Par exemple, dans Excel, si la cellule A1
présente la formule =1/0
, alors A1 affichera la valeur d’erreur #DIV0!
:
Si la cellule A2
fait référence à A1
avec une formule telle que =A1*2
, alors l’erreur se propage également à travers cette formule :
L’erreur remplace la valeur qui aurait autrement été calculée. Il n’y a pas de résultat pour la multiplication dans la cellule A2
, seulement l’erreur de la division dans A1
.
Power Fx fonctionne de la même manière. En général, si une erreur est fournie comme argument d’une fonction ou d’un opérateur, l’opération n’aura pas lieu et l’erreur de saisie sera considérée comme le résultat de l’opération. Par exemple, Mid( Text( 1/0 ), 1, 1 )
renvoie une erreur de division par zéro, car l’erreur la plus interne passe par la fonction Text et la fonction Mid :
En général, les erreurs ne transitent pas par les propriétés de contrôle Power Apps. Étendons l’exemple précédent avec un contrôle supplémentaire qui s’affiche si la propriété Text
de la première étiquette renvoie un état d’erreur :
Le fait que les erreurs ne se propagent pas à travers un contrôle ne pose pas de problème, car le système observera les erreurs sur l’entrée de toutes les propriétés du contrôle. L’erreur ne sera pas perdue.
La plupart des fonctions et des opérateurs suivent la règle « erreur d’entrée, erreur de sortie », mais il existe quelques exceptions. Les fonctions IsError, IsErrorOrBlank et IfError sont conçues pour fonctionner avec des erreurs, elles peuvent donc ne pas renvoyer d’erreur même si une erreur leur est transmise.
Observation des erreurs
Les erreurs ne sont pas observées tant que leur valeur n’est pas utilisée.
Par conséquent, les fonctions If et Select peuvent également ne pas renvoyer d’erreur si une erreur leur est transmise. Prenons la formule If( false, 1/0, 3 )
. Il y a une erreur de division par zéro présente dans cette formule, mais puisque la fonction If
n’emprunte pas cette branche à cause de la valeur false
, Power Fx et Power Apps ne signaleront pas d’erreur :
L’utilisation de la fonction Set avec une erreur ne renverra pas d’erreur au moment où l’erreur est placée dans la variable. Par exemple dans Power Apps, voici une formule dans la fonction App.OnStart qui place une erreur de division par zéro dans la variable x
:
Aucune erreur n’est signalée, car la valeur x
n’est pas référencée. Cependant, au moment où nous ajoutons un contrôle d’étiquette et définissons sa propriété Text sur x
, l’erreur s’affiche :
Vous pouvez observer les erreurs dans une formule avec les fonctions IfError, IsError et IsErrorOrBlank. Grâce à ces fonctions, vous pouvez renvoyer une autre valeur, prendre une autre mesure ou modifier l’erreur avant qu’elle ne soit observée et signalée.
Signalement d’erreurs
Après avoir observé une erreur, l’étape suivante consiste à signaler l’erreur à l’utilisateur final.
Contrairement à Excel, il n’y a pas toujours un endroit pratique pour afficher le résultat d’une erreur, car le résultat d’une formule peut piloter une propriété telle que les coordonnées X et Y d’un contrôle pour lequel il n’y a pas d’endroit pratique pour afficher du texte. Chaque hôte Power Fx contrôle la manière dont les erreurs sont finalement affichées à l’utilisateur final et le degré de contrôle que le créateur a sur ce processus. Dans Power Apps, une bannière d’erreur s’affiche et la fonction App.OnError est utilisée pour contrôler la manière dont l’erreur est signalée.
Il est important de noter que la fonction App.OnError ne peut pas remplacer l’erreur de la même manière que la fonction IfError. Au moment où la fonction App.OnError est exécutée, l’erreur s’est déjà produite et le résultat s’est propagé à travers d’autres formules. App.OnError contrôle uniquement la manière dont l’erreur est signalée à l’utilisateur final et fournit un moyen au créateur d’enregistrer l’erreur s’il le souhaite.
Les variables d’étendue FirstError et AllErrors fournissent des informations contextuelles sur l’erreur ou les erreurs. Cela fournit des informations sur le type d’erreur, l’origine de l’erreur et l’endroit où elle a été observée.
Arrêt après une erreur
Les formules de comportement prennent en charge l’action, la modification des bases de données et le changement d’état. Ces formules permettent d’effectuer plusieurs actions dans une séquence à l’aide de l’opérateur de chaînage ;
(ou ;;
selon les paramètres régionaux).
Dans ce cas, par exemple, le contrôle de grille affiche ce qui se trouve dans la table T
. Chaque bouton sélectionné modifie l’état dans cette table avec deux appels de la fonction Patch :
Dans une formule de comportement chaîné, les actions ne s’arrêtent pas après la première erreur. Modifions notre exemple pour transmettre un numéro d’index invalide dans le premier appel à la fonction Patch. Le deuxième appel à la fonction Patch continue malgré cette erreur précédente. La première erreur est signalée à l’utilisateur final et affichée comme une erreur dans Studio sur le contrôle :
IfError peut être utilisé pour arrêter l’exécution après une erreur. Semblable à la fonction If, le troisième argument de cette fonction fournit un emplacement pour placer des actions qui ne doivent être exécutées qu’en l’absence d’erreur :
Si une erreur survient pendant l’une des itérations de la fonction ForAll, le reste des itérations ne s’arrête pas. ForAll est conçu pour exécuter chaque itération indépendamment, permettant une exécution parallèle. Lorsque la fonction ForAll prend fin, une erreur est renvoyée, qui contient toutes les erreurs rencontrées (en examinant AllErrors dans la fonction IfError ou App.OnError).
Par exemple, dans la formule suivante, la fonction ForAll renvoie deux erreurs (pour la division par zéro pour Value
de 0, deux fois) et la fonction Collection
aura trois enregistrements (pour les cas où Value
n’est pas égal à 0) : [1, 2, 3]
.
Clear( Collection );
ForAll( [1,0,2,0,3], If( 1/Value > 0, Collect( Collection, Value ) ) );
Travailler avec plusieurs erreurs
Puisqu’une formule de comportement peut exécuter plusieurs actions, elle peut également rencontrer plusieurs erreurs.
Par défaut, la première erreur est signalée à l’utilisateur final. Dans cet exemple, les deux appels à la fonction Patch échouent, le second avec une erreur de division par zéro. Seule la première erreur (à propos de l’index) est affichée à l’utilisateur :
Les fonctions IfError et App.OnError peuvent accéder à toutes les erreurs rencontrées avec la variable d’étendue AllErrors. Dans ce cas, nous pouvons définir ceci sur une variable globale et examiner les deux erreurs rencontrées. Elles apparaissent dans la table dans l’ordre où elles ont été rencontrées :
Plusieurs erreurs peuvent également être renvoyées dans les formules sans comportement. Par exemple, l’utilisation de la fonction Patch avec un lot d’enregistrements à mettre à jour peut renvoyer plusieurs erreurs, une pour chaque enregistrement qui échoue.
Erreurs dans les tables
Comme nous l’avons vu précédemment, les erreurs peuvent être stockées dans des variables. Les erreurs peuvent également être incluses dans des structures de données, telles que des tables. Ceci est important pour qu’une erreur sur un enregistrement ne puisse pas invalider la table entière.
Par exemple, prenons ce contrôle de table de données dans Power Apps :
Le calcul dans AddColumns a rencontré une erreur de division par zéro pour l’une des valeurs. Pour cet enregistrement, la colonne Reciprocal a une valeur d’erreur (division par zéro) mais les autres enregistrements n’en ont pas et sont corrects. IsError( Index( output, 2 ) )
renvoie faux et IsError( Index( output, 2 ).Value )
renvoie vrai.
Si une erreur survient lors du filtrage d’une table, l’enregistrement entier est une erreur mais il est tout de même renvoyé dans le résultat afin que l’utilisateur final sache qu’il y avait quelque chose à cet endroit et qu’il y a un problème.
Prenons l’exemple suivant. Ici, la table d’origine ne contient pas d’erreurs, mais le fait de filtrer crée une erreur chaque fois que Value est égale à 0 :
Les valeurs -5 et -3 sont correctement filtrées. Les valeurs 0 entraînent une erreur dans le traitement du filtre, et il n’est donc pas clair si l’enregistrement doit être inclus ou non dans le résultat. Pour maximiser la transparence pour les utilisateurs finaux et aider les créateurs à déboguer, nous incluons un enregistrement d’erreur à la place de l’original. Dans ce cas, IsError( Index( output, 2 ) )
renvoie true.
Erreurs dans les sources de données
Les fonctions qui modifient les données dans les sources de données, telles que Patch, Collect, Remove, RemoveIf, Update, UpdateIf et SubmitForm signalent les erreurs de deux manières :
- Chacune de ces fonctions renverra une valeur d’erreur comme résultat de l’opération. Les erreurs peuvent être détectées avec IsError et remplacées ou supprimées avec IfError et App.OnError comme d’habitude.
- Après l’opération, la fonction Errors renverra également les erreurs des opérations précédentes. Cela peut être utile pour afficher le message d’erreur sur l’écran d’un formulaire sans avoir à capturer l’erreur dans une variable d’état.
Par exemple, cette formule recherche une erreur à partir de la fonction Collect et affiche un message d’erreur personnalisé :
IfError( Collect( Names, { Name: "duplicate" } ),
Notify( $"OOPS: { FirstError.Message }", NotificationType.Warning ) )
La fonction Errors renvoie également des informations sur les erreurs passées lors des opérations d’exécution. Elle peut être utile pour afficher une erreur sur l’écran d’un formulaire sans avoir à capturer l’erreur dans une variable d’état.
Relancer les erreurs
Parfois, certaines erreurs potentielles sont attendues et peuvent être ignorées en toute sécurité. Dans les fonctions IfError et App.OnError, si une erreur est détectée, elle doit être transmise au gestionnaire supérieur suivant. Vous pouvez relancer l’erreur à l’aide de Error( AllErrors )
.
Créer vos propres erreurs
Vous pouvez également créer vos propres erreurs avec la fonction Error.
Si vous créez vos propres erreurs, il est recommandé d’utiliser des valeurs supérieures à 1 000 pour éviter les conflits potentiels avec les futures valeurs d’erreur système.
Valeurs d’enum ErrorKind
enum ErrorKind | Valeur | Description |
---|---|---|
AnalysisError | 18 | Erreur système. Un problème s’est produit avec l’analyse du compilateur. |
BadLanguageCode | 14 | Un code de langue non valide ou non reconnu a été utilisé. |
BadRegex | 15 | Expression régulière non valide. Vérifiez la syntaxe utilisée avec les fonctions IsMatch, Match ou MatchAll. |
Conflict | 6 | L’enregistrement en cours de mise à jour a déjà été modifié à la source et le conflit doit être résolu. Une solution courante consiste à enregistrer les modifications locales, à actualiser l’enregistrement et à réappliquer les modifications. |
ConstraintViolated | 8 | L’enregistrement n’a pas passé un contrôle de contrainte sur le serveur. |
CreatePermission | 3 | L’utilisateur n’a pas l’autorisation de création d’enregistrement pour la source de données. Par exemple, la fonction Collect a été appelée. |
DeletePermissions | 5 | L’utilisateur n’a pas l’autorisation de suppression d’enregistrement pour la source de données. Par exemple, la fonction Remove a été appelée. |
Div0 | 13 | Division par zéro. |
EditPermissions | 4 | L’utilisateur n’a pas l’autorisation de création d’enregistrement pour la source de données. Par exemple, la fonction Patch a été appelée. |
GeneratedValue | 9 | Une valeur a été transmise par erreur au serveur pour un champ calculé automatiquement par le serveur. |
Usage Non valide | 16 | Utilisation non valide d’une fonction Souvent, un ou plusieurs des arguments de la fonction sont incorrects ou utilisés de manière non valide. |
FileNotFound | 17 | Le stockage SaveData est introuvable. |
InsufficientMemoy | 21 | Il n’y a pas assez de mémoire ou de stockage sur l’appareil pour l’opération. |
Annulation non valide | 25 | Un argument invalide a été transmis à une fonction. |
Internal | 26 | Erreur système. Il y a eu un problème interne avec l’une des fonctions. |
MissingRequired | 2 | Il manquait un champ d’enregistrement obligatoire. |
Network | 23 | Il y a eu un problème avec les communications du réseau. |
None | 0 | Erreur système. Il n’existe aucune erreur. |
Sans objet | 27 | Aucune valeur n’est disponible. Utile pour différencier une valeur vide qui peut être traitée comme un zéro dans les calculs numériques des valeurs vides qui doivent être signalées comme un problème potentiel si la valeur est utilisée. |
NotFound | 7 | Enregistrement introuvable. Par exemple, l’enregistrement à modifier dans la fonction Patch. |
NotSupported | 20 | Opération non prise en charge par ce lecteur ou cet appareil. |
Numérique | 24 | Une fonction numérique a été utilisée de manière inappropriée. Par exemple, la fonction Sqrt avec la valeur -1. |
QuotaExceeded | 22 | Quota de stockage dépassé. |
Valeur readOnly | 10 | La colonne est en lecture seule et ne peut pas être modifiée. |
ReadPermission | 19 | L’utilisateur n’a pas l’autorisation de lecture d’enregistrement pour la source de données. |
Synchroniser | 1 | Une erreur a été signalée par la source de données. Vérifiez la colonne Message pour plus d’informations. |
Inconnu | 12 | Une erreur d’un genre inconnu a eu lieu. |
Validation | 11 | L’enregistrement n’a pas passé un contrôle de validation. |