我是否需要在调用Win32 :: OLE-> LastError时捕获错误?

时间:2009-10-16 09:24:39

标签: perl winapi perl-critic

[编辑] - 事后看来,这个问题被误导了。我没有删除它,因为它是错误使用eval 的一个很好的例子,并通过 Perl :: Critic 进行正确的批评。

Perl Critic对下面的代码提出了以下批评:

  

未经测试的eval的返回值。您不能依赖$@/$EVAL_ERROR的值来判断eval是否失败

my $Jet = Win32::OLE->CreateObject('DAO.DBEngine.36')
    or croak "Can't create Jet database engine.";
my $DB = $Jet->OpenDatabase($DBFile)

# code omitted for the sake of brevity
# perl script writes results to Access db via an append query
$DB->Execute( $SQLquery, 128 );                       #128=DBFailOnError

eval {$err = Win32::OLE->LastError()} ; #<<<< PROBLEM LINE SEE FEEDBACK BELOW  
if ( $err){
     print $ERROR "WIN32::OLE raised an exception: $err\n";
     Win32::OLE->LastError(0);  # this clears your error
}

我的想法是我使用eval来检测错误对象的存在,并在Win32:OLE模块上检测错误并报告错误。

我可以安全地忽视这些批评吗?

2 个答案:

答案 0 :(得分:3)

暂不使用perl-critic版本,您的代码没有多大意义。

Win32::OLE docs解释何时抛出异常(以及如何自动捕获它们)。

假设您的程序没有死亡,

LastError只会在发生错误后向您提供有关错误的信息。将其包含在eval中是毫无意义的。

更新:我会写下以下内容(未经测试,因为我现在在Linux上,现在无法访问Windows):

use strict;
use warnings;

use Carp;

use Win32;
use Win32::OLE;

$Win32::OLE::Warn = 3;

# No need for this eval if you are OK with the default error message    
my $Jet = eval {
    Win32::OLE->CreateObject('DAO.DBEngine.36')
} or croak sprintf(
    "Can't create Jet database engine: %s", 
    win32_error_message(Win32::OLE->LastError)
);

# No need for this eval if you are OK with the default error message
my $DB = eval {
    $Jet->OpenDatabase($DBFile)
} or croak sprintf(
    "Can't open database '$DBFile': %s",
    win32_error_message(Win32::OLE->LastError)
);

my $result = eval {
    $DB->Execute( $SQLquery, 128 )
};

unless (defined $result) {
    print $ERROR win32_error_message(Win32::OLE->LastError);
    Win32::OLE->LastError(0);
}

答案 1 :(得分:2)

documentation详细说明了该消息的含义。简而言之,它告诉您在$@之后不单独依赖eval,而是还要检查eval的返回值。

但是,在您的情况下,问题是您没有检查eval的返回值,也不检查$@,而且您似乎使用了eval完全是多余的,因为你调用的方法不应该抛出任何异常。