Perl - Gestion des erreurs

L'exécution et les erreurs vont toujours de pair. Si vous ouvrez un fichier qui n'existe pas. alors si vous n'avez pas géré cette situation correctement, votre programme est considéré comme de mauvaise qualité.

Le programme s'arrête si une erreur se produit. Ainsi, une gestion correcte des erreurs est utilisée pour gérer divers types d'erreurs, qui peuvent se produire pendant l'exécution d'un programme et prendre les mesures appropriées au lieu d'arrêter complètement le programme.

Vous pouvez identifier et intercepter une erreur de différentes manières. Il est très facile de piéger les erreurs en Perl et de les gérer correctement. Voici quelques méthodes qui peuvent être utilisées.

L'instruction if

le if statementest le choix évident lorsque vous devez vérifier la valeur de retour d'une instruction; par exemple -

if(open(DATA, $file)) {
   ...
} else {
   die "Error: Couldn't open the file - $!";
}

Ici la variable $! renvoie le message d'erreur réel. Alternativement, nous pouvons réduire l'énoncé à une ligne dans les situations où cela a du sens de le faire; par exemple -

open(DATA, $file) || die "Error: Couldn't open the file $!";

La fonction sauf

le unlessfunction est l'opposé logique de if: les instructions peuvent contourner complètement l'état de réussite et être exécutées uniquement si l'expression renvoie false. Par exemple -

unless(chdir("/etc")) {
   die "Error: Can't change directory - $!";
}

le unlessL'instruction est mieux utilisée lorsque vous souhaitez déclencher une erreur ou une alternative uniquement si l'expression échoue. L'instruction a également du sens lorsqu'elle est utilisée dans une instruction sur une seule ligne -

die "Error: Can't change directory!: $!" unless(chdir("/etc"));

Ici, nous ne mourrons que si l'opération chdir échoue et qu'elle se lit bien.

L'opérateur ternaire

Pour des tests très courts, vous pouvez utiliser l'opérateur conditionnel ?:

print(exists($hash{value}) ? 'There' : 'Missing',"\n");

Ce que nous essayons de réaliser n'est pas aussi clair ici, mais l'effet est le même que l'utilisation d'un if ou unlessdéclaration. L'opérateur conditionnel est mieux utilisé lorsque vous souhaitez renvoyer rapidement l'une des deux valeurs d'une expression ou d'une instruction.

La fonction d'avertissement

La fonction d'avertissement déclenche simplement un avertissement, un message est affiché sur STDERR, mais aucune autre action n'est entreprise. Il est donc plus utile si vous souhaitez simplement imprimer un avertissement pour l'utilisateur et poursuivre le reste de l'opération -

chdir('/etc') or warn "Can't change directory";

La fonction die

La fonction die fonctionne comme warn, sauf qu'elle appelle aussi exit. Dans un script normal, cette fonction a pour effet de terminer immédiatement l'exécution. Vous devez utiliser cette fonction au cas où il serait inutile de continuer s'il y a une erreur dans le programme -

chdir('/etc') or die "Can't change directory";

Erreurs dans les modules

Il y a deux situations différentes que nous devrions être capables de gérer -

  • Signaler une erreur dans un module qui cite le nom de fichier et le numéro de ligne du module - cela est utile lors du débogage d'un module, ou lorsque vous souhaitez spécifiquement déclencher une erreur liée au module plutôt que liée au script.

  • Signaler une erreur dans un module qui cite les informations de l'appelant afin que vous puissiez déboguer la ligne dans le script qui a provoqué l'erreur. Les erreurs générées de cette manière sont utiles à l'utilisateur final, car elles mettent en évidence l'erreur par rapport à la ligne d'origine du script appelant.

le warn et dieLes fonctions fonctionnent légèrement différemment de ce à quoi vous vous attendez lorsqu'elles sont appelées depuis un module. Par exemple, le module simple -

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   warn "Error in module!";
}
1;

Lorsqu'il est appelé à partir d'un script comme ci-dessous -

use T;
function();

Il produira le résultat suivant -

Error in module! at T.pm line 9.

C'est plus ou moins ce à quoi vous pourriez vous attendre, mais pas nécessairement ce que vous voulez. Du point de vue d'un programmeur de module, les informations sont utiles car elles permettent de pointer vers un bogue dans le module lui-même. Pour un utilisateur final, les informations fournies sont assez inutiles, et pour tous sauf le programmeur aguerri, elles sont totalement inutiles.

La solution à ces problèmes est le module Carp, qui fournit une méthode simplifiée pour signaler les erreurs dans les modules qui renvoient des informations sur le script appelant. Le module Carp fournit quatre fonctions: carpe, gloussement, croassement et confession. Ces fonctions sont décrites ci-dessous.

La fonction carpe

La fonction carp est l'équivalent de base de warn et imprime le message dans STDERR sans réellement quitter le script et imprimer le nom du script.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   carp "Error in module!";
}
1;

Lorsqu'il est appelé à partir d'un script comme ci-dessous -

use T;
function();

Il produira le résultat suivant -

Error in module! at test.pl line 4

La fonction cluck

La fonction cluck est une sorte de carpe suralimentée, elle suit le même principe de base mais imprime également une trace de pile de tous les modules qui ont conduit à l'appel de la fonction, y compris les informations sur le script d'origine.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp qw(cluck);

sub function {
   cluck "Error in module!";
}
1;

Lorsqu'il est appelé à partir d'un script comme ci-dessous -

use T;
function();

Il produira le résultat suivant -

Error in module! at T.pm line 9
   T::function() called at test.pl line 4

La fonction croak

le croak fonction équivaut à die, sauf qu'il signale à l'appelant un niveau supérieur. Comme die, cette fonction quitte également le script après avoir signalé l'erreur à STDERR -

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   croak "Error in module!";
}
1;

Lorsqu'il est appelé à partir d'un script comme ci-dessous -

use T;
function();

Il produira le résultat suivant -

Error in module! at test.pl line 4

Comme pour la carpe, les mêmes règles de base s'appliquent en ce qui concerne l'inclusion des informations de ligne et de fichier selon les fonctions d'avertissement et de dé.

La fonction confesser

le confess la fonction est comme cluck; il appelle die et imprime ensuite une trace de pile jusqu'au script d'origine.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   confess "Error in module!";
}
1;

Lorsqu'il est appelé à partir d'un script comme ci-dessous -

use T;
function();

Il produira le résultat suivant -

Error in module! at T.pm line 9
   T::function() called at test.pl line 4