2010-07-08 16 views
4

我有一個數據庫查詢,我在一個評估中運行,以捕獲錯誤。問題在於錯誤消息正在輸出到控制檯,即使它正在被困住。如何阻止這樣做的錯誤信息,因爲我想自己解析並吐出我自己的消息?爲什麼我在控制檯上看到DBI錯誤,即使我在eval中包裝了DBI調用?

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 
} 

回答

6

您可以在connect調用指定'PrintError => 0(或使用HandleError):

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

或每個語句句柄來設置:

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

而且,不依賴於$ @爲我指出錯誤。使用eval更好的方法是:

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

也許''HandleError'也可以使用,如果你要沿(Print | Raise)錯誤路線走。 – vol7ron 2010-07-08 16:08:03

+0

@ vol7ron HandleError也是一種可能性,但我從來沒有發現它的好用,因爲我通常只是在eval {}中包裝代碼塊來捕獲所有異常,而不僅僅是DBI錯誤。 – runrig 2010-07-08 16:55:40

+1

您也可以爲每個語句句柄設置一些這些屬性。 – 2010-07-08 20:02:23

2

eval { }意願陷阱致命錯誤(來自dieCarp::croak呼叫),但不是非致命錯誤消息(來自warn或)。爲了處理警告信息,請參閱如何安裝文檔警告處理程序%SIGwarn

一個平凡的解決方法是使用你的eval塊中一個微不足道的警告處理。

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

參見:perlfaq7: How do I temporarily block warnings?

+2

等等等等等等,你肯定是要抑制你的警告消息等等等等一個好主意。 – mob 2010-07-08 15:23:28

+0

** @ mobrule:**我認爲那是被問到的。 'local $ SIG {__ WARN__} = sub {}'是顯而易見的選擇。 http://perldoc.perl.org/functions/warn.html – vol7ron 2010-07-08 15:57:09

+0

雖然這是一個正確的解決方案,以在一個'eval'塊抑制警告,在'connect'方法指定'PrintError => 0'是正確的方式處理OP的情況。 – 2010-07-08 17:23:13

13

這不是一個好主意,陷阱,忽略錯誤,不管它們是致命與否。此外,這是不可取的檢查$ @的方式,你正在做的(參見有關Perl例外更好的方式在本網站中的問題來捕獲異常,我在下面用Try::Tiny,這可以說是所有的最輕重量路線) 。

而是連同DBI操作行進時較早的一個可能失敗,你應該在每一步檢查錯誤條件:

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 
}; 

請記住,總是use strict; use warnings;模塊和腳本。你的代碼摘錄表明你還沒有這樣做。

+2

我的代碼示例是我正在使用的_minimum_viable_示例。因此,諸如警告和嚴格的內容已被刪除,以及其他評估性陳述。但感謝您的參與。您的答案將完全保存在問題上,並通過爲Try:Tiny提供的有用鏈接得到滿意的結果。 – 2010-07-08 16:25:13

+5

@Ben:我從'$ sth = ...'推斷出這個,​​而不是'my $ sth = ...'。沒有必要粗魯。 – Ether 2010-07-08 16:34:33

+2

對你自己也一樣。假設任何關於如何從7行代碼構建腳本是非常粗魯的。 – 2010-07-08 16:42:40

相關問題