%ERROR
Détecter une erreur avec l'extension (E)
Renvoie *ON si la dernière opération marquée de l'extension (E) a provoqué une erreur, ce qui évite l'arrêt du programme.
Syntaxe
%ERROR
- Résultat
- Un indicateur : *ON si l'opération avec (E) a échoué, *OFF sinon. Un enregistrement non trouvé ou une fin de fichier ne sont pas des erreurs.
À quoi ça sert
Sans extension (E), une erreur d'entrée-sortie arrête le programme avec un message RNQ (l'exemple 3 en montre un). Avec chain(e), write(e), open(e)… l'erreur est mémorisée et le programme continue : on teste %ERROR, puis %STATUS pour connaître la cause.
C'est le moyen de traiter proprement un cas prévisible (doublon à l'écriture, fichier à ouvrir) sans passer par un bloc monitor.
Exemple 1 : CHAIN(E) sur des clients dont l'un est en erreur
**free
// %ERROR : intercepter une erreur d'E-S avec (E) au lieu de laisser planter le programme.
ctl-opt dftactgrp(*no) actgrp(*new);
// Pas de alwnull : une date NULL dans le fichier declenche une erreur de lecture
dcl-f client keyed;
dcl-s cle packed(5:0);
for cle = 100 to 500 by 100;
chain(e) (cle) client;
if %error;
snd-msg 'Client ' + %char(cle) + ' : ERREUR, statut ' + %char(%status(client));
elseif %found(client);
snd-msg 'Client ' + %char(cle) + ' : ' + %trim(nom) + ', cree le ' + %char(datcre);
else;
snd-msg 'Client ' + %char(cle) + ' : absent';
endif;
endfor;
cle = 250;
chain(e) (cle) client;
snd-msg 'Client 250 : %ERROR = [' + %char(%error) + '] %FOUND = [' + %char(%found(client)) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Client 100 : Dupont SA, cree le 2020-03-15
Client 200 : Martin et fils, cree le 2021-11-02
Client 300 : ERREUR, statut 1299
Client 400 : Bernard Transports, cree le 2019-06-30
Client 500 : Petit Atelier, cree le 2024-01-08
Client 250 : %ERROR = [0] %FOUND = [0]
Le client 300 a une date de création NULL. Comme le programme ne déclare pas alwnull, le CHAIN échoue avec le statut 1299 (erreur de mappage de données) : %ERROR vaut 1 et la boucle continue. Le client 250, absent, n'est pas une erreur : %ERROR vaut 0 et %FOUND vaut 0.
Exemple 2 : WRITE(E) et clé en double
**free
// %ERROR sur une ecriture : cle en double.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);
dcl-f f_client usage(*output) keyed;
clear f_clientr;
numcli = 100;
nom = 'Doublon SARL';
ville = 'Nice';
write(e) f_clientr;
if %error;
snd-msg 'Ecriture refusee, statut ' + %char(%status(f_client));
else;
snd-msg 'Client cree';
endif;
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Ecriture refusee, statut 1021
Le client 100 existe déjà dans la copie F_CLIENT : l'écriture est refusée avec le statut 1021 et le programme affiche un message au lieu de s'arrêter.
Exemple 3 : Un piège d'état, puis le plantage sans (E)
**free
// %ERROR reste allume apres une operation sans (E), puis le programme plante sans (E).
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-f client keyed;
chain(e) (300) client;
snd-msg 'CHAIN(E) 300 : %ERROR = [' + %char(%error) + '] statut ' + %char(%status(client));
// Ce CHAIN se passe bien, mais il n'a pas de (E) : %ERROR n'est pas remis a zero
chain (100) client;
snd-msg 'CHAIN 100 sans (E) : %ERROR = [' + %char(%error) + '] statut ' + %char(%status(client));
chain(e) (100) client;
snd-msg 'CHAIN(E) 100 : %ERROR = [' + %char(%error) + ']';
// Sans (E), la meme erreur arrete le programme
chain (300) client;
snd-msg 'Cette ligne n''est jamais atteinte';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
CHAIN(E) 300 : %ERROR = [1] statut 1299
CHAIN 100 sans (E) : %ERROR = [1] statut 0
CHAIN(E) 100 : %ERROR = [0]
Erreur : RNQ1299 - (C G D F) Erreur d'E-S CPF5029 détectée sur fichier CLIENT.
Cet exemple s'arrête volontairement sur une erreur : le dernier CHAIN n'a pas d'extension (E), donc le message RNQ1299 est émis et le programme s'arrête (la ligne suivante n'est jamais exécutée). Avant cela, on voit que %ERROR reste à 1 après un CHAIN sans (E) qui a pourtant réussi.
Le piège
%ERROR n'est mis à jour que par les opérations qui portent l'extension (E). Dans le troisième exemple, un chain (100) sans (E) réussit, et pourtant %ERROR vaut toujours 1, avec un statut à 0. Il faut mettre (E) sur chaque opération dont on teste le résultat, et tester %ERROR juste après.
Autre point : sans (E), la même erreur arrête le programme (message RNQ1299 dans l'exemple). Enfin, %ERROR ne dit pas quelle erreur s'est produite ; c'est %STATUS qui donne le code.