2011-08-03 31 views
2

我是Perl中的新手。 我有一個運行在http:// localhost:19000的JSON-RPC服務器,我需要調用checkEmail()方法。Perl - 使用JSON :: RPC :: Client時出現'不是HASH參考'錯誤

use JSON::RPC::Client; 

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

my $callobj = { 
    method => 'checkEmail', 
    params => [ '[email protected]' ], 
}; 

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 
+0

使用'perl -MCarp :: Always ./check_ac。pl'來獲得一個完整的堆棧跟蹤和一個關於代碼中問題出現的更好的線索。 – mob

+0

它說「無法找到鯉魚/ Always.pm」。我已經嘗試使用MCarp :: Always安裝它,但無法找到 –

+0

嘗試安裝Carp :: Always,而不是MCarp :: Always。 -M只是意味着從命令行使用「。 – gpojd

回答

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()不檢查JSON->decode()在嘗試作爲hashref訪問它之前返回的是什麼類型的東西。鑑於你的錯誤,我會繼續前進,並假設你的情況是而不是之一。 :-)

我不知道是否有辦法從您的代碼強制修復。我建議聯繫author並讓他知道問題,和/或filing a bug

+0

'JSON :: RPC :: Client'通過假設返回值是一個hashref來正常工作;這是協議的要求。對於這個問題,當然,更好的錯誤信息會更好。 – darch

+0

但正如我所指出的,'JSON :: decode()'仍然可以返回其他類型的標量。 'JSON' perldoc明確指出這種情況。錯誤在於'JSON :: RPC :: ReturnObject'不應該假設它會總是在'$ content'中獲得一個hashref,除非它調用的創建它的方法已經保證它總是會提供。正如你所說,似乎有另一個bug潛伏在這裏某處(即 - 爲什麼*不是*本應該返回的hashref?),但是「不是HASH引用」錯誤是由驗證不足引起的在'ReturnObject'的ctor中。 –

+0

是的,在JRC負責提供良好的錯誤消息傳遞時,是否有責任與JSON-RPC服務器之外的某些東西進行交互,這是有爭議的(事實上,我至少在「 JRC的消息來源暗示作者本人不知道該走哪條路)。但我也不認爲指出這一事實本身就足夠有幫助。 – darch

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_postJSON::RPC::Client以這樣的方式來讓你檢查一下Web服務器響應我們提出的要求,居然說在內部進行調用。以上代碼轉儲頁面的文本內容;這可能不適合你的情況,如果遇到錯誤會炸燬。這只是一種調試幫助,可以幫助您從客戶端代碼找出服務器出了什麼問題。

我想現在已經有足夠的警告了。祝你好運。

相關問題