Impression de messages d’erreur

Je me demande simplement quel est le meilleur moyen de créer des fonctions d’erreur d’impression personnalisées.

Par exemple, j’ai quelques définitions comme celle-ci dans le fichier d’en-tête:

#define SOCKET_ERR 0 #define BIND_ERR 1 #define LISTEN_ERR 2 etc 

Alors peut-être en utilisant ceci comme ceci:

 if(/*something has gone wrong with socket*/) { print_error(SOCKET_ERR); } print_error(int error) { if(error == 0) { printf("Socket failure\n"); } } 

Cependant, je ne pense pas que cela soit parfait et que je veuille faire quelque chose de beaucoup mieux. Peut-être quelque chose d’un peu plus professionnel et peut-être plus évolutif.

Merci beaucoup pour tout conseil,

Vous pouvez envisager d’utiliser des fonctions variadiques pour signaler les erreurs, elles deviennent ainsi beaucoup plus polyvalentes.

Par exemple

 #include  void my_error(FILE *out, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(out, fmt, ap); va_end(ap); } 

Ce qui pourrait être appelé comme ceci (note, je suppose un compilateur c99):

 my_error(stderr, "%s: Invalid range of %ld near line %d", __func__, range, __LINE__); 

Cela pourrait facilement être lié à d’autres réponses suggérant que des codes d’erreur pourraient être définis dans des listes énumérées, avec un tableau constant de chaînes pour les traduire. Je vais laisser cela comme un exercice pour le lecteur. Il est très facile de faire en sorte que l’exemple ci-dessus accepte plus d’arguments.

NB: Si vous utilisez quelque chose comme char buffer [LEN] pour personnaliser la chaîne imprimée, changez-la de void à unsigned int, demandez-lui de renvoyer le nombre d’octets que vsnprintf () n’a pas pu imprimer, cela pourrait être utile à l’appelant. L’exemple ci-dessus est «sûr», dans lequel vous n’avez pas à vous soucier du dépassement de la mémoire tampon allouée à la stack avec un message d’erreur formaté de longueur indéfinie. Ou laissez-le vide et faites-le imprimer ce qu’il peut (tout en notant qu’il ne peut pas tout imprimer), à vous de choisir. L’inconvénient de cette approche réside dans le fait que nous ne connaissons pas bien la longueur des arguments variadiques une fois développés. Après tout, vous signalez des résultats inattendus 🙂

Cette approche vous permet de vous aider davantage en véhiculant des messages d’erreur significatifs et informatifs, ainsi qu’en les enregistrant simplement dans un fichier ouvert.

Je sais que cet exemple décrit fondamentalement printf () lui-même. Je le poste pour montrer à quel point il est facile de s’adapter et de se développer.

Consultez log4c pour quelques idées sur l’implémentation de la journalisation.

Voici un conseil: Ne vous contentez pas d’imprimer “il ya une erreur”. Donnez autant d’informations que possible: Quelle adresse IP? Code d’erreur? Qu’est-ce que votre code a essayé de réaliser?

Lorsque vous avez besoin d’écrire un message d’erreur, posez-vous la question suivante: De quoi aurai-je besoin de savoir quand ce message d’erreur apparaît? Qu’est-ce qui m’aidera à résoudre le problème?

Vous pouvez aussi faire quelque chose comme ça:

 //Enum for the error codes typedef enum { SOCKET_ERR = 0, BIND_ERR, LISTEN_ERR, LAST_ENTRY //This SHOULD be the last entry } ErrorCode; //Error descriptions..number of ensortinges should match the number of ensortinges in Enum const char* errorDesc[] = { "Socket failure", "Bind failure", "Listen failure", "Dummy" }; void printError(ErrorCode c) { //Validate.. if( c < LAST_ENTRY) { printf(errorDesc[c]); } }