Perl - 使用JSON :: RPC :: Client时出现'不是HASH引用'错误

时间:2011-08-03 15:39:36

标签: perl json-rpc

我是Perl的新手。 我有一个运行在 http:// localhost:19000 的JSON-RPC服务器,我需要调用 checkEmail()方法。

use JSON::RPC::Client;

my $client = new JSON::RPC::Client;
my $url    = 'http://localhost:19000';

my $callobj = { 
    method  => 'checkEmail',
    params  => [ 'rprikhodchenko@gmail.com' ],
};

my $res = $client->call($url, $callobj);

if($res) {
     if ($res->is_error) {
         print "Error : ", $res->error_message;
     }   
     else {
         print $res->result;
     }   
  }
  else {
     print $client->status_line;
  }

当我尝试启动它时,它会告诉以下内容:

perl ./check_ac.pl
Not a HASH reference at /usr/local/share/perl/5.10.1/JSON/RPC/Client.pm line 193.

UPD:

完整堆栈跟踪:

perl -MCarp::Always ./check_ac.pl
Not a HASH reference at /usr/local/share/perl/5.10.1/JSON/RPC/Client.pm line 193
        JSON::RPC::ReturnObject::new('JSON::RPC::ReturnObject', 'HTTP::Response=HASH(0x9938d48)', 'JSON=SCALAR(0x96f1518)') called at /usr/local/share/perl/5.10.1/JSON/RPC/Client.pm line 118
        JSON::RPC::Client::call('JSON::RPC::Client=HASH(0x944a818)', 'http://localhost:19000', 'HASH(0x96f1578)') called at ./check_ac.pl line 11

2 个答案:

答案 0 :(得分:3)

此错误意味着您的JSON-RPC服务器实际上不是一个,因为它不满足requirement 7.3。当JSON::RPC::Client假定JSON-RPC服务返回的文档格式正确(即JSON对象)时,会触发该错误,并且此假设结果是错误的。向JSON::RPC::Client作者提交的错误报告将是请求更好的错误消息传递的适当方式。

我会通过找出导致JSON::RPC::Client阻塞的服务器返回的内容来攻击此类问题。不幸的是,JRC无法提供足够的钩点来找到它,所以你必须有点棘手。

我不喜欢编辑外部库,因此我建议使用扩展和覆盖方法来检测JSON-RPC服务器的流量。这样的事情(在check_ac.pl中):

use Data::Dumper qw();

package JSON::RPC::InstrumentedClient;
use base 'JSON::RPC::Client';

# This would be better done with Module::Install, but I'm limiting dependencies today.
sub _get {
    my ($self, @args) = @_;

    return $self->_dump_response($self->SUPER::_get(@args));
}

sub _post {
    my ($self, @args) = @_;

    return $self->_dump_response($self->SUPER::_post(@args));
}

sub _dump_response {
    my ($self, $response) = @_;

    warn Data::Dumper::Dump([$response->decoded_content], [qw(content)]);
    return $response;
}

package main;

my $client = JSON::RPC::InstrumentedClient->new();
my $url    = 'http://localhost:19000';

... # rest of check_ac.pl

这将_get_post内部JSON::RPC::Client的调用包含在内,以便让您检查Web服务器为响应我们的请求而实际说明的内容。上面的代码转储了页面的文本内容;这可能不是你的情况下正确的事情,如果遇到错误会爆炸。它只是一个调试辅助工具,可以帮助您从客户端代码中找出服务器出了什么问题。

我认为现在有足够的警告。祝你好运。

答案 1 :(得分:0)

method new of JSON::RPC::ReturnObject似乎是一个错误。

sub new {
    my ($class, $obj, $json) = @_;
    my $content = ( $json || JSON->new->utf8 )->decode( $obj->content );

    #...
# line 193
    $content->{error} ? $self->is_success(0) : $self->is_success(1);
    #...
}

$content的值将是JSON::decode()来电返回的内容。但是看一下文档,似乎JSON->decode()返回一个标量,可以是数字,字符串,数组引用,哈希引用。

不幸的是,JSON::RPC::ReturnObject->new()在尝试将其作为hashref访问之前不会检查JSON->decode()返回的内容。鉴于你的错误,我将继续并假设它在你的情况下得到的是一个。 : - )

我不知道是否有办法强制修复代码。我建议您联系author并告知他相关问题,和/或filing a bug