9
votes

Perl: Attraper une erreur sans matrice

Je joue avec la manipulation des erreurs et j'ai un petit problème. Je connecte une base de données à l'aide du module DBI.

Je fais ma propre gestion des erreurs en utilisant un sous-programme que j'appelle une erreur. P>

Je peux attraper mes propres matrices et les gérer tout à fait Ma connexion de base de données échoue, le module DBI imprime apparemment sa propre matrice: P>

DBI Connect (...) a échoué: ORA-12154: TNS: ne pouvait pas résoudre le identifiant de connexion spécifié (erreur DBD: ociserverattach) à ... p> blockQuote>

Comment allais-je attraper cela? p>

J'ai essayé d'utiliser $ sig {__ die __} code> comme: p>

local $SIG{__DIE__} = sub {
  my $e = shift;
  print "Error: " .$e;
};


0 commentaires

5 Réponses :


2
votes

Il y a beaucoup d'interrupteurs dans DBI, comme PrintErthError, FermerError, etc. que vous pouvez ajuster. Voir http://search.cpan.org/perldoc?dbi


2 commentaires

HMM n'est-il pas une solution plus générique? Afin que je puisse attraper toutes les autres erreurs avec 1 fonction. Je pourrais utiliser beaucoup de modules qui ont beaucoup de façons de produire des erreurs, je veux être indépendant de cela ..


DBI a également une méthode de guérisseur. Ou si vous définissez ImprimerError sur FALSE, FRAYError à TRUE, votre traitement des erreurs (PMARCOEN) doit être appelé.



3
votes

D'accord, j'ai trouvé la solution, apparemment, j'avais besoin de __ warn __ au lieu de __ matrice __ et ce morceau de code nécessaire pour être en haut du fichier, avant l'emplacement de l'erreur. jeté, contrairement à l'exemple que j'ai lu indiqué :)


1 commentaires

C'est correct, c'était un avertissement et non une mort, et le gestionnaire doit être installé en premier. Vous pouvez l'installer dans n'importe quel module si vous l'enveloppez dans un commencer {} .



0
votes

Ce n'est pas aussi générique qu'un receveur de matrice global, mais spécifiquement pour la gestion des erreurs DBI, nous avons notre propre module fournissant des wrappers autour des appels de base de données; et l'une des fonctionnalités du module consiste à envelopper eval (en fonction d'un drapeau) autour de chaque appel DBI.

Cela nous permet de faire la manipulation des erreurs personnalisées sur le niveau d'accès aux données, telles que les tentatives de requête, les statistiques, le basculement automatisé et plus encore - tous transparents au reste du code.


0 commentaires

9
votes

DBI Connect (...) a échoué: ORA-12154: TNS: ne pouvait pas résoudre le problème Identifiant spécifié (erreur DBD: Ociserverattach) à ... p>

Comment allais-je attraper cela? p>

Pour attraper et gérer ce niveau d'erreur, utilisez Eval In BLOCK FORM, "EVAL {...}". Cela attirera tout matrice qui se produit dans le sous-code. Si le code dans un bloc d'évaluation meurt, il définira $ @ et le bloc retournera false. Si le code ne meurt pas, $ @ sera réglé sur ''. P>

Utilisation de la manipulation du signal via SIG {Warn} et SIG {DIE} est gênante car ils sont globaux, il existe également des conditions de course à considérer (Que se passe-t-il si je reçois un signal pendant que je gère un signal différent? etc. Les problèmes traditionnels de l'informatique basée sur le signal). Vous écrivez probablement un code à un seul fileté, vous n'êtes donc pas inquiet des problèmes de simultanéité de plusieurs choses qui appellent mourir, mais il y a l'utilisateur à considérer (peut-être qu'il enverra un sigkill pendant que vous essayez d'ouvrir la connexion DBI ) P>

Dans ce cas particulier, vous utilisez DBI. Avec DBI, vous pouvez contrôler ce qui se passe dans le cas de l'erreur, s'il doit mourir, avertir ou échouer silencieusement et attendre que vous vérifiez l'état de retour. P>

Voici un exemple de base d'utiliser EVAL { ...}. P>

my $dbh = eval { DBI->connect( @args) };
if ( $@ )
{
    #DBI->connect threw an error via die
    if ($@ =~ m/ORA-12154/i )
    {
        #handle this error, so I can clean up and continue
    }
    elsif ( $@ =~ m/SOME \s* other \s* ERROR \s+ string/ix )
    {
       #I can't handle this error, but I can translate it
        die "our internal error code #7";
    }
    else 
    {
      die $@; #re-throw the die
    }
}

1 commentaires

C'était la façon dont je l'avais au début, évaluez cependant n'atteignons pas les avertissements que je voulais signaler aussi. Je dois utiliser SIG {avertir}.



3
votes

Inclure ceci dans votre SIG {__ Die __} Code> Bloc:

### Check if exceptions being caught.
return if $^S;


0 commentaires