如果我设置RaiseError = 1
,连接或执行时会引发什么异常?
如果我要在execute()
try
中包围我的catch
方法,我应该抓住exception
那个?
答案 0 :(得分:2)
The Perl Error.pm module, which provides try
and catch
, is deprecated.异常,因为它们存在于Perl中,是无类型的,这就是你如何捕获它:
eval {
do_something_which_may_throw_exception();
};
if ($@) {
print "Exception: $@\n";
};
简而言之,eval { ... }
块充当“try”,if ($@) { ... }
充当“catch”,其中异常文本包含在特殊变量$@
中。
答案 1 :(得分:2)
DBI documentation列出并解释了很多选项,其中许多与错误处理有关。
Perl有两个主要的错误处理习惯用语:
die
有一些错误消息(致命)。默认情况下,DBI使用第一个习语。错误原因在$DBI::errstr
。为此,您必须检查每次调用DBI API的返回值。
当你感到懒惰时,你可以使用例外。在句柄构造函数中设置RaiseError
将使DBI方法抛出异常。来自文档:
RAISEERROR
输入:boolean,inherited
RaiseError
属性可用于强制错误引发异常,而不是简单地以正常方式返回错误代码。它默认是“关闭”。设置为“on”时,任何导致错误的方法都会导致DBI有效地执行die("$class $method failed: $DBI::errstr")
,其中$class
是驱动程序类,$method
是方法的名称失败。如,DBD::Oracle::db prepare failed: ... error text here ...
[...]
通常
RaiseError
与eval { ... }
一起用于捕获已抛出的异常,然后是if ($@) { ... }
块来处理捕获的异常。例如:eval { ... $sth->execute(); ... }; if ($@) { # $sth->err and $DBI::err will be true if error was from DBI warn $@; # print the error ... # do whatever you need to deal with the error }
在该eval块中,如果您无法确定哪个句柄触发了错误,则
$DBI::lasth
变量可用于诊断和报告。
正如您所看到的,Perl中的异常不是使用try / catch处理,而是使用eval { ... }
处理。在eval
die
之后,$@
错误变量将设置为该错误,您可以自由处理它。请注意,DBI不使用异常对象。
答案 2 :(得分:2)
如果您想从DBI获取正式的异常对象,可以使用HandleError
属性和Exception::Class::DBI。我自己用它。从概要:
use DBI;
use Exception::Class::DBI;
my $dbh = DBI->connect($dsn, $user, $pass, {
PrintError => 0,
RaiseError => 0,
HandleError => Exception::Class::DBI->handler,
});
eval { $dbh->do($sql) };
if (my $ex = $@) {
print STDERR "DBI Exception:\n";
print STDERR " Exception Type: ", ref $ex, "\n";
print STDERR " Error: ", $ex->error, "\n";
print STDERR " Err: ", $ex->err, "\n";
print STDERR " Errstr: ", $ex->errstr, "\n";
print STDERR " State: ", $ex->state, "\n";
print STDERR " Return Value: ", ($ex->retval || 'undef'), "\n";
}