在我之前的question中,建议我使用模块Crypt::OpenSSL::RSA
导出和发送RSA密钥。但是,我发现这个模块似乎无法处理非致命错误,因此只需发送格式错误的字符串(即不是RSA密钥),服务器程序在尝试使用创建新对象时就会崩溃它带有消息:
server.pl第46行无法识别的密钥格式
第46行包含代码
$clients{$cur_client}->{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message) or do {
server_log "Bad key exchange, dropping user $address:$port...";
delete $clients{$cur_client};
next;
}; # Key exchange
我该如何解决这个问题?
答案 0 :(得分:6)
您需要使用eval
的BLOCK格式来防止程序在引发异常时死亡。不幸的是,eval
的使用充满了尴尬的角落情况,最好使用Try::Tiny
模块来处理这些问题
为了达到你的问题代码的目的,你会写这样的东西。显然,您必须为变量
提供有用的数据 值得注意的是,try
和catch
是子例程。这意味着您需要在catch
之后使用分号,并且next
内不能catch
,因为您无法在子例程中执行此操作。您必须保留某种状态集,以便后续代码可以在那里执行任何必要的操作,在这种情况下,我只检查$clients{$cur_client}
是否仍然存在 - 它将被catch
例程删除有一个问题
还有必要解释die
例程中$_
catch
字符串中的catch
字符串,因此您可以查看失败的原因。在这种情况下,unrecognized key format
期望只处理die $_
个错误,因此代码会检查这确实是失败的原因。如果没有,那么它会发出另一个use strict;
use warnings 'all';
use Crypt::OpenSSL::RSA;
use Try::Tiny;
my %clients = ( aa => {} );
my $message = 'xxx';
my ($address, $port) = qw/ 127.0.0.1 80 /;
for my $cur_client ( keys %clients ) {
try {
$clients{$cur_client}{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message);
}
catch {
if ( /unrecognized key format/ ) {
server_log("Bad key exchange, dropping user $address:$port...");
delete $clients{$cur_client};
}
else {
die $!;
}
};
next unless exists $clients{$cur_client};
# More handling of $cur_client in the case that
# the call to new_public_key succeeds
}
sub server_log {
print "Logging: $_[0]\n";
}
以反映发生了未处理的错误
NSApplication.sharedApplication()
let delegate = AppDelegate()
NSApplication.sharedApplication().delegate = delegate
答案 1 :(得分:0)
我知道这已经得到了解答,但我想我会添加它,以便人们意识到你不需要一个模块来捕获Perl中的错误,它已经内置了。这里有一些代码来演示Perls内置的异常处理......
#!/usr/bin/perl
use strict;
use warnings;
my $a = 100;
my $res = 0;
eval {
$res = $a/0;
};
if($@) {
print("I just caught a divide by zero here... $@\n");
}
另一个例子......
eval {
die "please die\n";;
};
if($@) {
print("No, you cannot die just yet... $@\n");
}
我已经使用了这个成语多年,它的工作就像一个魅力。