即使我已将 DBI 调用包装在 eval 中,为什么我仍会在控制台上看到 DBI 错误?

发布于 2024-09-08 20:06:44 字数 349 浏览 9 评论 0原文

我有一个在 eval 中运行的数据库查询,以捕获错误。问题是错误消息正在输出到控制台,即使它被捕获。当我想自己解析它并吐出我自己的消息时,如何阻止错误消息这样做?

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

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

if($@){
    #Do my parse/print stuff here I know
}

I have a database query that I am running inside an eval, to trap the error. Problem is that the error message is outputting to console, even though it is being trapped. How do I stop the error message from doing this, as I want to parse it myself and spit back my own messages?

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

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

if($@){
    #Do my parse/print stuff here I know
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

饮惑 2024-09-15 20:06:44

捕获和忽略错误都不是一个好主意,无论它们是否致命。另外,不建议以您正在执行的方式检查 $@ (请参阅本网站上有关 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
};

并记住,始终 使用严格;在每个模块和脚本中使用警告;。您的代码摘录表明您尚未执行此操作。

It's not a good idea to trap and ignore errors, whether they are fatal or not. Also, it is not advisable to check $@ in the way you are doing it (see the questions on this site about perl exceptions for better ways to trap exceptions; I use Try::Tiny below, which is arguably the lightest-weight route of all).

Instead of proceeding with a DBI operation when an earlier one might have failed, you should check error conditions at every step:

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

And remember, always use strict; use warnings; in every module and script. Your code excerpt suggests that you are not yet doing this.

﹏半生如梦愿梦如真 2024-09-15 20:06:44

您可以指定 'PrintError => 0' 在您的 connect 调用中(或使用 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 $@
}

You can specify 'PrintError => 0' in your connect call (or use HandleError):

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

Or to set per statement handle:

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

Also, don't depend on $@ for indicating an error. A better way to use eval is:

my $result = eval {
  ...
  $sth->...etc.
  1;
}
unless ($result) {
  # Do error handling..log/print $@
}
素罗衫 2024-09-15 20:06:44

eval { } 将捕获致命错误(来自 dieCarp::croak 调用),但不会捕获非致命错误消息(来自 warncarp)。要处理警告消息,请参阅 %SIG< 的文档中如何安装警告处理程序/code>警告

一个简单的解决方法是在您的 eval 块中使用一个简单的警告处理程序。

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

另请参阅:perlfaq7:如何暂时阻止警告?

eval { } will trap a fatal error (from a die or Carp::croak call), but not a non-fatal error message (from warn or carp). To handle warning messages, see how to install a warning handler in documentation for %SIG or warn.

A trivial workaround is to use a trivial warning handler inside your eval block.

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

See also: perlfaq7: How do I temporarily block warnings?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文