2011-08-03 2 views
2

저는 Perl의 초보자입니다. 에서 실행중인 JSON-RPC 서버가 http : // localhost : 19000이며, 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

"Carp/Always.pm을 찾을 수 없습니다"라고 표시됩니다. MCarp :: Always를 사용하여 설치를 시도했지만 항상 찾을 수 없습니다. –

+0

MCp :: Always가 아닌 Carp :: 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()은 hashref로 액세스하려고 시도하기 전에 JSON->decode()이 어떤 종류의 것을 반환했는지 확인하지 않습니다. 당신의 실수를 감안할 때, 나는 당신의 경우에 무엇이 들어 왔는지를 가정하고 이 아니라고 가정합니다.입니다. :-)

코드에서 수정 프로그램을 강제로 실행할 수 있는지 알 수 없습니다. author에 연락하여 문제를 알리고 filing a bug을 알리는 것이 좋습니다.

+0

'JSON :: RPC :: Client'는 반환 값이 hashref라고 가정하여 올바르게 동작합니다. 그것은 프로토콜의 요구 사항입니다. 물론이 질문의 목적을 위해 더 나은 오류 메시징이 더 좋을 것입니다. – darch

+0

하지만 JSON :: decode()는 다른 유형의 스칼라를 반환 할 수 있습니다. 'JSON' perldoc은 그것이 사실이라고 명시 적으로 말합니다. 버그는'JSON :: RPC :: ReturnObject'는'$ content'에서 hashref를 항상 가져올 것이라고 가정해서는 안됩니다. 생성하려고하는 메소드가 그것이 항상 보장할만한 것이 아니라면 제공하십시오. 무슨 말인지 알겠지만, 어딘가에 숨어있는 또 다른 버그가있는 것 같습니다 (즉, 왜 *는 해시 참조가 있어야했을 때 돌아온 것이 아닌지)?하지만 "해시가 아님"오류는 유효성 검사가 충분하지 않아서 발생했습니다. 'ReturnObject'의 ctor에 저장합니다. –

+0

예, JSON-RPC 서버가 아닌 뭔가와 상호 작용할 때 좋은 오류 메시지를 제공하는 것이 JRC의 책임인지에 대한 논쟁의 여지가 있습니다 (사실, 나는' JRC' 출처는 저자 자신이 어떤 방향으로 나아갈 지 확신 할 수 없다고 제안했다. 그러나 나는 또한이 사실을 지적하는 것이 그 자체로 충분하다고는 생각하지 않는다. – darch

3

이 오류는 requirement 7.3을 만족하지 않는 JSON-RPC 서버가 실제로 하나가 아니라는 것을 의미합니다. 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 

_getJSON::RPC::Client을 사용하면 웹 서버가 실제로 우리가 만든 요청에 ​​대한 응답으로 말을 살펴 보자하는 방식으로 내부적으로 만드는 것을 _post에 대한 호출을 래핑합니다. 위의 코드는 페이지의 텍스트 내용을 덤프합니다. 이것은 귀하의 경우에 옳지 않을 수 있으며 오류가 발생하면 폭발합니다. 클라이언트 코드 측면에서 서버의 문제점을 파악하는 데 도움이되는 디버깅 도구입니다.

지금은 충분히주의해야합니다. 행운을 빕니다.

관련 문제