2010-07-08 14 views
4

J'ai une requête de base de données que je cours dans un eval, pour piéger l'erreur. Le problème est que le message d'erreur sort en console, même s'il est piégé. Comment puis-je arrêter le message d'erreur, car je veux l'analyser moi-même et cracher mes propres messages?Pourquoi est-ce que je vois des erreurs DBI sur la console même si j'ai enveloppé les appels DBI dans un eval?

my $dbh = DBI->connect('dbi:Pg:dbname=database;host=localhost', 
    'user', 'pass', 
    {RaiseError => 1} 
); 

eval{ 
    $sth = $dbh->prepare($sql); 
    $sth->execute; 
}; 

if([email protected]){ 
    #Do my parse/print stuff here I know 
} 

Répondre

6

Vous pouvez spécifier 'PrintError => 0' dans votre connect appel (ou utilisez HandleError):

my $dbh = DBI->connect('dbi:Pg:dbname=database;host=localhost', $user, $passwd, { 
    PrintError => 0, 
    RaiseError => 1, 
}); 

ou pour régler par poignée de déclaration:

my $sth = $dbh->prepare("SELECT * from my_table"); 
$sth->{PrintError} = 0; 
$sth->execute(); 
...etc. 

aussi, ne dépendent pas de @ M $ pour i ndicating une erreur. Une meilleure façon d'utiliser eval est:

my $result = eval { 
    ... 
    $sth->...etc. 
    1; 
} 
unless ($result) { 
    # Do error handling..log/print [email protected] 
} 
+2

Peut-être que 'HandleError' pourrait également être utilisé, si vous descendez la route d'erreur (Imprimer | Élever). – vol7ron

+0

@ vol7ron HandleError est aussi une possibilité, mais je n'en ai jamais trouvé un bon usage puisque je ne fais qu'emballer des blocs de code dans eval {} pour attraper toutes les exceptions, pas seulement les erreurs DBI. – runrig

+1

Vous pouvez également définir certains de ces attributs par handle d'instruction. –

2

eval { } piégera une erreur fatale (d'un appel die ou Carp::croak), mais pas un message d'erreur non fatale (de warn ou). Pour gérer les messages d'avertissement, voir comment installer un gestionnaire d'avertissement dans la documentation pour %SIG ou warn.

Une solution triviale est d'utiliser un gestionnaire d'avertissement trivial dans votre bloc eval.

eval { 
    local $SIG{__WARN__} = sub { }; 
    ... 
}; 

Voir aussi: perlfaq7: How do I temporarily block warnings?

+2

bla bla bla êtes-vous sûr que c'est une bonne idée de supprimer votre message d'avertissement bla bla. – mob

+0

** @ mobrule: ** Je pense que c'est ce qui était demandé. 'local $ SIG {__ WARN__} = sub {}' est le choix évident. http://perldoc.perl.org/functions/warn.html – vol7ron

+0

Bien que ce soit une bonne solution pour supprimer les avertissements dans un 'eval' bloc, en spécifiant' PrintError => 0' dans la méthode 'connect' est la bonne façon de gérer la situation de l'OP. –

13

Ce n'est pas une bonne idée de piéger et ignorer les erreurs, si elles sont fatales ou non. En outre, il est conseillé de vérifier $ @ dans la façon dont vous le faites (voir les questions sur ce site au sujet des exceptions de Perl pour de meilleures façons de piéger les exceptions, j'utilise Try::Tiny ci-dessous, qui est sans doute la route le plus léger de tous) .

Au lieu de procéder à une opération DBI lorsqu'un plus tôt on aurait pu échoué, vous devez vérifier les conditions d'erreur à chaque étape:

use strict; use warnings; 
use Try::Tiny; 

try { 
    my $sth = $dbh->prepare($sql) or die $dbh->errstr; 
    $sth->execute or die $sth->errstr; 
} catch { 
    print "got error $_\n"; 
    # return from function, or do something else to handle error 
}; 

Et rappelez-vous, toujoursuse strict; use warnings; dans tous les modules et script. Votre extrait de code suggère que vous ne le faites pas encore.

+2

Mon exemple de code était l'exemple _minimum_viable_ de ce que je travaillais. Par conséquent, des choses comme les avertissements et les stricts ont été retirées, ainsi que d'autres déclarations d'évaluation. Mais merci de jouer. Votre réponse est sauvegardée à partir de l'emballage complet sur la question et une downvote par le lien utile fourni pour Try: Tiny. –

+5

@Ben: J'ai déduit cela de '$ sth = ...' plutôt que 'my $ sth = ...'. Il n'y a pas besoin d'être impoli. – Ether

+2

La même chose pour vous. Il est assez impoli de supposer quelque chose sur la façon dont un script est construit à partir de 7 lignes de code. –