> Tech > Supervision des erreurs

Supervision des erreurs

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

Nous avons vu jusqu'ici comment utiliser les BIF et le coding défensif pour prévenir ou traiter les erreurs évidentes. Mais toutes ne le sont pas. Prenons un exemple simple :

z = (a - b) / (c - d)

C'est la différence entre les deux qui compte :

if (c

Supervision des erreurs

– d) <> 0;
z = (a – b) / (c – d);
endif;

Mais cette approche n’est pas idéale
parce que l’opération If produit un écho
de la moitié de l’assignation. Avec des implications
sur la performance, la lisibilité
et la facilité de maintenance au fur et à  mesure
que les équations se compliquent. La
solution ci-dessus serait à  la rigueur acceptable
si elle était solide. Mais elle ne l’est pas. Voyons ce
qui se passe si (a – b) est très grand et (c – d) est très petit : on
risque la troncature. Et notre code défensif ne s’en préoccupe
nullement. C’est là  que le bon sens intervient. S’il est
peu probable qu’une erreur risque de se produire, alors il
faut la superviser et la corriger :

monitor;
z = (a – b) / (c – d);
on-error;
z = 0;
endmon;

Cet exemple utilise un groupe monitor pour tester une
erreur. Un groupe monitor teste les erreurs sur les opérations
entre le Monitor et les premières opérations On-Error.
Si une erreur se produit, le contrôle est transmis au bloc de
code On-Error approprié. Si toutes les opérations réussissent,
le contrôle est transmis à  l’opération EndMon. Dans ce
cas, le bloc monitor met z à  zéro en cas d’erreur.
Un groupe monitor peut inclure de multiples instructions
On-Error qui testent les conditions d’erreur spécifiques,
ainsi que le On-Error attrape-tout, comme le montre
le fragment de code précédent. L’exemple suivant supervise
explicitement la division par zéro (00102) et la troncature
(00103) :

monitor;
z = (a – b) / (c – d);on-error 00102;
// Handle divide by zero
on-error 00103;
// Handle truncation
on-error;
// Handle other errors
endmon;

L’instruction On-Error peut spécifier des conditions multiples
en les séparant par des signes deux-points ou en utilisant
les mots réservés suivants :

  • Program intercepte les conditions de
    programme 00100 à  00999.
  • File intercepte les conditions de programme
    01000 à  09999.
  • All intercepte les conditions de programme
    et de fichier.

A noter que les conditions 00001 à 
00099 ne peuvent pas être supervisées.
(Pour la liste complète des conditions,
voir le chapitre 5, File and Program
Exceptions/Errors, du manuel ILE RPG
Reference à  publib.boulder.ibm.com/
iseries/v5r3/ic2924/books/c0925084
.pdf).
Les groupes monitor peuvent être
imbriqués. Si une erreur se produit à 
l’intérieur de groupes monitor imbriqués,
le groupe le plus à  l’intérieur qui
peut intercepter l’erreur reçoit le
contrôle des opérations. Les groupes
monitor ne peuvent pas intercepter les
erreurs exécutées dans des sous-routines
séparées. Cependant, ils peuvent
intercepter les erreurs dans des procédures
ou des programmes appelés qui
n’interceptent pas leurs propres erreurs
mais se terminent avec la condition
00202 : Called program or procedure
failed. Si une procédure supervise
une erreur, l’instruction On-Error reçoit
le contrôle. Si une procédure ne
contient pas un monitor, l’instruction
On-Error appropriée dans la procédure
appelante reçoit le contrôle.
Les groupes monitor imbriqués
dans la même procédure ou dans des
procédures imbriquées peuvent ajouter
au code une complexité elle-même
génératrice de ses propres erreurs. Il
vaut donc mieux privilégier la simplicité.
Il faut partir du principe que
chaque procédure contrôlera sa propre
reprise sur erreur.
Assurez-vous que votre reprise sur erreur est complète et
aboutit à  l’effet souhaité. Voyons l’exemple suivant :

monitor;
a= x;
b = y;
c = z;
on-error;
// Handle errors
endmon;

Comment le code devrait-il traiter les erreurs ? Une erreur pourrait se produire sur n’importe laquelle des trois
assignations. Supposons que ce code soit exécuté en boucle.
Au deuxième cycle, une erreur survient sur la deuxième assignation.
A a été assigné, B a échoué. C conserve encore sa valeur
du cycle précédent.
L’une des manières de traiter une erreur consiste à  tout
remettre à  plat :

monitor;
a= x;
b = y;
c = z;
on-error;
a= 0;
b = 0;
c = 0;
endmon;

Cette méthode convient quand A, B et C
sont dépendants et qu’une erreur sur l’un
quelconque des champs devrait invalider les
trois. Toutefois, il existe deux alternatives. Premièrement, effacer
tous les champs de résultats avant qu’ils ne soient assignés
et utiliser le groupe monitor pour intercepter l’exception
:

a = 0;
b = 0;
c = 0;
monitor;
a= x;
b = y;
c = z;
on-error;
// Do nothing
endmon;

Cette technique est bonne si l’on veut assigner des variables
jusqu’à  une erreur.
Autre possibilité, diviser le groupe monitor en trois
groupes simples sous la forme

monitor;
a= x;
on-error;
a = 0;
endmon;

Cette technique donne de bons résultats quand on veut
tenter les trois assignations indépendamment des erreurs.
Même avec un bloc de code simple, on peut traiter les erreurs
de multiples manières. La bonne méthode est celle qui
reflète l’objectif du code. Quel que soit l’objectif, assurezvous
que votre méthode expose et récupère les erreurs autant
que nécessaire. L’essentiel est de ne pas les cacher :

monitor;
a= x;
on-error;
// Do nothing
endmon;

Ce genre de code aggrave la situation en transformant
une erreur explosive en une radioactive.
Tous les exemples d’erreurs d’assignation que j’ai montrés
jusqu’ici effectuent la reprise en attribuant une valeur
par défaut (0). Quand c’est judicieux, un genre de reprise sur
erreur qui permet à  l’application de continuer son exécution
sans interruption est préférable. Cependant, dans certains
cas, les erreurs sont tellement graves qu’il faut les exposer. Mais cela ne signifie pas forcément que le programme doive
s’arrêter. Souvent, il suffit d’afficher l’erreur à  l’écran, dans
un rapport, ou dans un fichier de journalisation, puis de procéder
à  la reprise et de poursuivre l’exécution.
Si l’on adopte cette méthode, il faut intercepter les détails
de l’erreur. Pour les erreurs de programme, on trouvera
les détails dans la structure des données d’état du programme,
comme le montre la figure 3. Pour les erreurs d’I/O,
on trouvera les détails dans la structure de données d’information
de fichier (figure 4). Les deux structures de données
incluent des sous-champs qui définissent l’état de l’erreur,
son ID message correspondant et autres données pertinentes.
Pour intercepter l’erreur qui nous intéresse, on utilise
les mots réservés *Program et *File sur l’opération On-
Error :

monitor;
// Do something;
on-error *program;
status = program.status;
on-error *file;
status = fileInfo.status;
endmon;

Pour plus d’informations sur les structures de données
d’état des programmes et d’information des fichiers, voir le
chapitre 5 du manuel ILE RPG Reference.

Téléchargez cette ressource

Préparer l’entreprise aux technologies interconnectées

Préparer l’entreprise aux technologies interconnectées

Avec la « quatrième révolution industrielle », les environnements hyperconnectés entraînent de nouveaux risques en matière de sécurité. Découvrez, dans ce guide Kaspersky, comment faire face à cette nouvelle ère de vulnérabilité.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010