2011-08-03 4 views
2

私はPerlの初心者です。 私はJSON-RPCサーバーをhttp:// localhost:19000で実行しています。checkEmail()メソッドに電話する必要があります。Perl - JSON :: RPC :: Clientを使用しているときに 'Not a HASH reference'エラーが発生しました

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

「Carp/Always.pmを見つけることができません」と表示されます。私はMCarp :: Alwaysを使用してインストールしようとしましたが、それは見つかりません。 –

+0

MCp :: AlwaysではなくCarp :: Alwaysをインストールしてみてください。 -Mは、コマンドラインから "use"を意味します。 – 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()あなたのエラーを考えて、私は先に進み、あなたのケースで何が得られたかをではなく、と仮定します。 :-)

コードから修正を強制する方法があるかどうかわかりません。私はauthorに連絡し、彼に問題について、そして/またはfiling a bugを知らせることをお勧めします。

+0

'JSON :: RPC :: Client'は戻り値がハッシュリファレンスであると仮定して正しく動作します。それはプロトコルの要件です。もちろん、この質問の目的のために、より良いエラーメッセージが良いでしょう。 – darch

+0

しかし、私が指摘したように、 'JSON :: decode()'は他の型のスカラーを返すことができます。 'JSON' perldocはそうであることを明示しています。バグは、 'JSON :: RPC :: ReturnObject'は' $ content'でハッシュリファレンスを取得すると仮定してはいけません。作成するメソッドがそれを保証するものでなければ提供する。あなたが言っているように、ここにはどこかに潜んでいる別のバグがあるようです(つまり、どうしたら*ハッシュリファレンスが返されていなかったのですか?)しかし、 "ハッシュリファレンスではありません" 'ReturnObject'のctorに入れます。 –

+0

ええ、JSON-RPCサーバーではないものとやりとりしているときに良いエラーメッセージを提供することがJRCの責任であるかどうかについて議論の余地があります(実際には、著者自身がどのように行くべきか分からないと示唆している)。しかし、私はまた、この事実を指摘すること自体が十分に役立つとは考えていません。 – darch

3

このエラーは、requirement 7.3を満たしていないため、実際にはJSON-RPCサーバーが1つではないことを意味します。 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 

これは、Webサーバが実際に私たちが作った要求に応答して言っ調べてみましょうするようJSON::RPC::Clientがこのような方法で、内部的に作ること_get_postへの呼び出しをラップします。上記のコードは、ページのテキストコンテンツをダンプします。これはあなたのケースでは適切ではないかもしれませんし、エラーが発生した場合には爆発します。これは、デバッグの助けになるだけで、クライアントコード側からサーバーの何が問題なのかを理解するのに役立ちます。

これは十分な注意点です。がんばろう。

関連する問題