La gestion des erreurs avec un pgm OPM (non ILE) est la suivante: 1/ l'erreur est-elle gérée par le pgm ? - routine de gestion d'erreur spécifique au langage (MONMSG en CL, *PSSR/INFSR ou indicateur en RPG, ...) la routine prend le contrôle et décide de la suite à donner 2/ si non, routine de gestion d'erreur par défaut (système) - "Message xxxxxx reçu par pgm xxxxxxxxx, spécif xxxx (C D S F) ?" le système prend le contrôle et gère la suite. Si l'erreur n'est pas gérée, le système envoie un message "function check" (CPF9999) pour prévenir d'une erreur non traitée, en remontant la liste d'invocation, jusqu'à ce qu' un programme gère l'erreur ou jusqu'à une fin anormale du travail. |
Avec ILE, il existe deux niveaux pouvant intervenir en plus Vous pouvez définir une procédure (dont l'écriture est à votre charge) qui sera déclarée responsable des erreurs à venir (appel automatique) en RPG la priorité est la suivante : 1/ indicateur dans la colonne << sur l'ordre lui même ou extension (E) et utilisation de %error, %status 2/ *INFSR 3/ la routine "condition handler" dont nous parlons 4/ *PSSR 5/ la routine standard de gestion d'erreur (message C,D,G,F ? ) |
Cela peut être fait de deux manières: A/ directement par le langage (cette définition est prioritaire) directive #pragma en C/400 (directive destinée au compilateur) sous la forme #pragma cancel_handler (procédure , 0 ) ou (procédure , com-area) [com-area est une variable permettant la transmission d'infos) B/ par appel de l'API liable CEEHDLR qui fait référence à une procédure. (l'api CEEHDLU annule cette déclaration) Et la gestion d'une erreur non traitée est différente, le système renvoie LA MEME ERREUR, au pgm précédent dans la liste d'invocation (la doc dit "to percolate"), jusqu'à la rencontre d'un pgm d'un autre groupe d'activation qui reçoit le message CEE9901 "application ended". |
Soit la liste d'invocation suivante : pgm/procédure groupe d'activation proc1 A proc2 B proc3 A proc4 A En effet, dans la liste d'invocation, un groupe d'acivation n'est pas forcement continu (il peut y avoir des aller-retour) Si proc4 reçoit une erreur MCHxxxx non monitorée : l'erreur MCHxxxx est envoyée à proc3 à l'instruction du CALLB ou CALLPRC (proc3 fait partie du même groupe d'activation A). Si proc3 ne gère toujours pas l'erreur : le message CEE9901 est envoyée à proc2 (changement de groupe A -> B) puis CEE9901 est envoyé à proc1 sur le même principe. |
A ce stade il faut définir deux notions complémentaires - Handle cursor & resume cursor Il s'agit de deux pointeurs définissant respectivement : - le point de contrôle d'erreur en cours il s'agit (pour le niveau d'appel en cours et dans l'ordre de recherche) 1/ d'une procédure de contrôle direct (#pragma) 2/ d'une procédure de condition ILE (API CEEHDLR) 3/ d'une routine spécifique au langage si le système ne trouve pas de routine gérant l'erreur il passe au niveau d'appel précédant en recommençant la recherche. - le point de reprise suite à erreur il est par défaut l'instruction qui suit l'erreur, modifiable via l'API liable CEEMRCR ou par la procédure de condition. |
- Token Identifiant d'une erreur différent du message ID, en effet les compilateurs ILE étant communs à la gamme IBM (SAA), la gestion des erreurs est commune. Il s'agit d'une info sur 12 Octets 1 à 4 . CONDITION ID (N° d'erreur ILE) 1 à 2. Gravité en clair (2 octets binaires) 3 à 4. N° de message système (à associer à FACILITY ID) 5 à 5 . Flags bits 1 et 2 : CASE (environnement, ILE = 1) bits 3,4,5 : gravité bits 6,7,8 : divers flags 6 à 8 . FACILITY ID (groupe de messages : CEE,CPF,MCH) 9 à 12. Clé du message associé |
Il y a une correspondance entre le type de message, sa sévérité et la gravité ILE. type ! sévérité (système) ! gravité ILE ! Signification ! -----------------------------------------------!---------------! *STATUS ! 0 ! 0 ! info ! ou !-------------------- !---------------!---------------! *NOTIFY ! 01 à 99 ! 1 ! attention ! -----------------------------------------------!---------------! ! 00 à 29 ! 2 ! erreur ! !---------------------!---------------!---------------! *ESCAPE ! 30 à 39 ! 3 ! err/sévère ! !---------------------!---------------!---------------! ! 40 à 49 ! 4 ! err/grave ! ---------------------------------------------------------------- Seuls les messages *STATUS,*NOTIFY et *ESCAPE pouvant être monitorés (cela ne change pas) |
APIs liables de gestion des erreurs ILE - CEEHDLR Définir la procédure de gestion d'erreur ILE. + *procptr. Pointeur de procédure en RPG D PTR * PROCPTR INZ(*NULL) résolu par C EVAL PTR = %PADDR(nom-pgm) ou bien D PTR * INZ(%PADDR(nom-pgm)) + comarea variable de communication D comarea S 16A ou bien D message S nnA D comarea S * INZ(%addr(message)) La procédure reçoit : - le token de la condition - l'adresse de comarea renseignés par > - code retour la procédure > - token de la nouvelle condition |
Les codes retour peuvent être les suivants: 10 Ignorer et continuer (au resume cursor) vous pouvez modifier le "resume cursor" avec l'API CEEMRCR. 20 Ne pas gérer l'erreur et basculer vers le handle cursor suivant 21 Ne pas gérer l'erreur et basculer (to percolate) vers le point d'entrée au-dessus, dans la liste d'invocation. (impossible cependant de sortir du groupe d'activation) 30 Promouvoir (to promote) une autre erreur (envoyer une autre erreur à la place), vers le handle cursor suivant 31 idem, vers le point d'invocation au-dessus 32 idem, vers le point d'invocation actuel (le processus est relancé) Pour promouvoir un message vous devez renseigner le token de la nouvelle condition. |
- CEEHDLU Annuler la procédure de gestion des erreurs ILE. + *procptr. Pointeur de procédure - CEEMRCR Définir le resume cursor + BIN(4) 0 = point d'entrée du handle cursor 1 = un niveau au-dessus du handle cursor - CEENCOD contruire un token + BIN(2) 1 ère partie du code erreur (= SEVERITY) + BIN(2) 2 ème partie + BIN(2) CASE (1 = ILE) + BIN(2) SEVERITY (0 à 4) + BIN(2) CONTROL + CHAR(3) FACILITY ID (CEE,CPF,MCH) + BIN(4) clé du message + CHAR(12) token en retour |
- CEEDCOD décomposer un token + CHAR(12) token à décomposer + BIN(2) 1 ère partie du code erreur (= SEVERITY) + BIN(2) 2 ème partie + BIN(2) CASE (1 = ILE) + BIN(2) SEVERITY (0 à 4) + BIN(2) CONTROL + CHAR(3) FACILITY ID (CEE,CPF,MCH) + BIN(4) clé du message - CEESGL signale une erreur ILE + CHAR(12) token de la condition à signaler Toutes ces APIs (et toutes les APIs liables) ont un paramètre en plus, optionnel, qui est un token en retour, renseigné par l'API si celle-ci a détecté une erreur. Si ce paramètre n'est pas utilisé, l'API envoie un message qui déroulera tout le processus que nous venons de voir ! |
Les APIs CEEHDLR, CEEHDLU n'existent pas en tant que procédures. (la doc dit que ce sont des fonctions "BUILTIN") Elles sont reconnues par le compilateur qui les interprètent et génère le code correspondant. Lors d'une erreur le système appel un procédure liée (dans QLEAWI) qui se nomme "Q LE HdlrRouterEh", qui elle même passe le contrôle à la procèdure déclarée "Condition Handler" (responsable des erreurs). Cette procédure peut se trouver dans un programme de service lié. (voir l'exemple associé à ce cours) Le Condition Handler étant associé à un niveau d'appel, l'utilisation de l'API CEEHDLU est facultaive, le Condition Handler est désactivé avec la fin du programme. |