Gestion des erreurs sous X Window

 

Introduction

Si votre gestionnaire de fenêtres le permet, vous avez certainement la possibilité de fermer votre fenêtre via une croix en haut à droite de celle-ci ou encore dans un menu (voire souvent les deux !).

Cependant, si vous choisissez cette option, votre programme va lamentablement se planter avec un message vous indiquant que vous avez perdu la connexion avec le serveur...

En fait, le programme de gestion de fenêtres a mis fin à la connexion, mais vous n'en avez pas été informé !!!

Pour le moment, nous n'allons par regarder comment être informé de cette déconnexion. Mais nous allons en profiter pour étudier la gestion des erreurs (Ce n'est donc pas la solution pour détecter la terminaison d'un programme, mais un prétexte pour étudier la gestion des erreurs !)

La gestion des erreurs est donc liée aux erreurs de communications entre votre application et le serveur. Soit la requète que vous envoyez ne peut pas être interprétée correctement, soit, il y a un problème avec le serveur qui ne répond pas par exemple !

Sous X Window, il y a donc deux types d'erreurs qui peuvent se produire:

- Les erreurs dites fatales. Dans ce cas, vous devez mettre fin à votre programme, car vous ne pourrez rien faire d'autre (hormis sauver le travail en cours bien sûr !). Le cas de déconnexion du serveur est une erreur fatale !

- Les erreurs non fatales ! Ce sont des erreurs repérées au niveau du serveur. Vous pourrez toujours essayer de continuer le traitement, mais souvent, ce type de problème sera lié à un bug dans votre programme. Ce cas est par exemple causé lors de l'uilisation d'un identifiant d'une fenêtre qui est inexistante ou a été détruite précédemment.

Cette gestion des erreurs est donc à faire lorsque vous enverrez des requètes au serveur pour voir si la connexion est bien établie, mais aussi lorsque vous allez écouter ce que répond le serveur. S'il s'agit d'une annonce d'une erreur, alors les fonctions d'écoutes vont automatiquement lancer le traitement correspondant.

 

Intercepter les erreurs fatales

int (*XSetIOErrorHandler(handler))()
int (*handler)(Display *);

Cette fonction va permettre de remplacer le code standard de gestion des erreurs fatales par la votre. Cette fonction attend donc l'adresse de votre routine de gestion des erreurs fatales. Par exemple:

En entrée:

L'adresse de votre fonction de gestion des erreurs fatales se nomme ErrorIOTrap()

int ErrorIOTrap (Display* dpy)

{

...Le code de traitements des erreurs fatales...

}

Il suffira donc de taper ceci:

XSetIOErrorHandler (ErrorIOTrap);

 

En sortie: L'adresse de la précédente routine de gestion des erreurs fatales.

 

 

Intercepter les erreurs non fatales

De la même manière, vous pourrez détourner la gestion des erreurs non fatales sur une fonction perso.:

int (*XSetErrorHandler(handler))()
int (*handler)(Display *, XErrorEvent *)

En sortie: L'adresse de la précédente routine de gestion des erreurs non fatales.

Dans ce cas, votre fonction recevra un pointeur sur une structure de type XErrorEvent.

Voici un exemple de fonction:

Restera alors à faire XSetErrorHandler(ErrorHandler);

 

Image non trouvée !Il sera possible de traduire le code erreur en texte en utilisant la fonction:(Il faudra mettre au début de votre code: #include <X11/Xproto.h>)

XGetErrorText(display, code, buffer_return, length)
Display *display;
int code;
char *buffer_return;
int length;

En entrée:

display est la valeur retournée par XopenDisplay()

code est le code erreur dans le membre error_code de XerrorEvent

buffer_return est un pointeur sur une chaine de caractères qui va recevoir le texte correspondant au code erreur dans la langue d'installation du système.

length et la taille maximum de notre buffer_return.

 

ou encore la fonction

XGetErrorDatabaseText(display, name, message, default_string, buffer_return, length)
Display *display;
char *name, *message;
char *default_string;
char *buffer_return;
int length;

En entrée:

display ... toujours le même !

name qui contiendra le nom de notre application

message type du message d'erreur

default_string message a charger si non trouvé dans la base de message (normalement, il faudra prendre soins à transmettre le message dans la langue correspondant à celle de l'installation de la machine...)

buffer_return est un pointeur sur une chaine de caractères qui va recevoir le texte correspondant au code erreur dans la langue d'installation du système.

length et la taille maximum de notre buffer_return.

 

 

Redéfinir les fonctions par défaut de gestion des erreurs fatales ou non

Image non trouvée !Pour réinitialiser les deux fonctions de gestion des erreurs vous réutilisez XSetIOErrorHandler ou XSetErrorHandler. Soit vous mettez les valeurs récupérées lors du premier appel aux fonctions de gestion des erreurs, soit vous passez la valeur 0.

 

Aperçu de la gestion de la file d'événements

Pour traiter ces erreurs, vous allez devoir écouter le serveur. Le fait d'écouter sera en fait suffisant pour que vos programmes de gestions des erreurs se lancent automatiquement... Vous n'aurez donc rien à faire d'autres. Il ne s'agit donc pas ici d'expliquer les événements (pour plus de détails voir ici...)

Vous aurez besoin de la fonction XNextEvent (dpy, &event) pour lire le contenu de la file d'évènements. Cependant, cette fonction est bloquante. Ce qui veut dire que votre traitement bloquera s'il n'y a pas d'évènement à traiter. Pour éviter cela, vous utiliserez une autre fonction non bloquante cette fois qui vous indiquera s'il y a un évènement à traiter:

XPending (dpy) qui est différent de 0 si au moins un évènement est dans la file.

La gestion détaillée de le file des événements est expliquée dans le chapitre suivant : "Boucle d'attente d'événements"

Voici un exemple de code repris du chapitre "Boucle d'attente d'événements":

Exemple de gestion des erreurs

Dans l'exemple qui suit, je vais provoquer des erreurs non fatales:

La première sera retournée après avoir tenté de modifier le titre d'une fenêtre n'existant pas.

La seconde sera retournée suite à la création d'une fenêtre fille sur une fenêtre n'existant pas.

 

L'erreur fatale pourra être générée par la fermeture de notre fenêtre. Le programme perdant la connexion avec le serveur, vous aurez donc cette erreur !

Image non trouvée !