File Coverage

blib/lib/JSON/RPC/Spec/Procedure.pm
Criterion Covered Total %
statement 46 47 97.8
branch 14 14 100.0
condition 7 7 100.0
subroutine 9 9 100.0
pod 1 1 100.0
total 77 78 98.7


line stmt bran cond sub pod time code
1             package JSON::RPC::Spec::Procedure;
2 8     8   19275 use Moo;
  8         9862  
  8         35  
3 8     8   2885 use Carp ();
  8         8  
  8         97  
4 8     8   22 use Try::Tiny;
  8         7  
  8         459  
5             with qw(
6             JSON::RPC::Spec::Common
7             );
8              
9 8   100 8   25 use constant DEBUG => $ENV{PERL_JSON_RPC_SPEC_DEBUG} || 0;
  8         8  
  8         813  
10              
11             has router => (
12             is => 'ro',
13             required => 1,
14             isa => sub {
15             my $self = shift;
16             $self->can('match') or Carp::croak('method match required.');
17             },
18             );
19              
20 8     8   3085 use namespace::clean;
  8         52729  
  8         32  
21              
22              
23             sub parse {
24 49     49 1 1471 my ($self, $obj, $extra_args) = @_;
25 49 100       102 if (ref $obj ne 'HASH') {
26 4         9 return $self->_rpc_invalid_request;
27             }
28 45         99 $self->_is_notification(!exists $obj->{id});
29 45         84 $self->_id($obj->{id});
30 45   100     97 my $method = $obj->{method} || '';
31              
32             # rpc call with invalid Request object:
33             # rpc call with an invalid Batch (but not empty):
34             # rpc call with invalid Batch:
35 45 100 100     243 if ($method eq '' or $method =~ m!\A\.|\A[0-9]+\z!) {
36 9         23 return $self->_rpc_invalid_request;
37             }
38 36         22 my ($result, $err);
39             try {
40 36     36   679 $result = $self->_trigger($method, $obj->{params}, $extra_args);
41             }
42             catch {
43 13     13   317 $err = $_;
44 13         25 warn qq{-- error : @{[$err]} } if DEBUG;
  36         3924  
45 36         175 };
46 8 100       17 if ($self->_is_notification) {
47 28         51 return;
48             }
49 9 100       7 if ($err) {
50 9         34 my $error;
51 4 100       13 if ($err =~ m!rpc_method_not_found!) {
    100          
52 1         3 $error = $self->_rpc_method_not_found;
53             }
54             elsif ($err =~ m!rpc_invalid_params!) {
55 4         44 $error = $self->_rpc_invalid_params;
56             }
57             else {
58 9         226 $error = $self->_rpc_internal_error(data => $err);
59             }
60 19         44 return $error;
61             }
62             return +{
63 0         0 jsonrpc => $self->_jsonrpc,
64             result => $result,
65             id => $self->_id
66             };
67             }
68              
69             # trigger registered method
70             sub _trigger {
71 37     37   1336 my ($self, $name, $params, $extra_args) = @_;
72 37         66 my $router = $self->router;
73 37         84 my $matched = $router->match($name);
74              
75             # rpc call of non-existent method:
76 37 100       1362 unless ($matched) {
77 6         733 Carp::croak 'rpc_method_not_found on trigger';
78             }
79 31         74 my $cb = delete $matched->{$self->_callback_key};
80 31         842 return $cb->($params, $matched, @{$extra_args});
  31         70  
81             }
82              
83             1;
84             __END__