File Coverage

blib/lib/Mojo/WebSocketProxy/Backend/JSONRPC.pm
Criterion Covered Total %
statement 50 62 80.6
branch 5 12 41.6
condition 7 16 43.7
subroutine 10 10 100.0
pod 2 2 100.0
total 74 102 72.5


line stmt bran cond sub pod time code
1             package Mojo::WebSocketProxy::Backend::JSONRPC;
2              
3 17     17   105 use strict;
  17         31  
  17         441  
4 17     17   70 use warnings;
  17         25  
  17         401  
5              
6 17     17   69 use parent qw(Mojo::WebSocketProxy::Backend);
  17         26  
  17         76  
7              
8 17     17   923 use feature qw(state);
  17         41  
  17         1102  
9              
10 17     17   94 no indirect;
  17         32  
  17         121  
11              
12 17     17   9075 use curry;
  17         3922  
  17         511  
13              
14 17     17   5839 use MojoX::JSON::RPC::Client;
  17         28922  
  17         87  
15              
16             our $VERSION = '0.11'; ## VERSION
17              
18             __PACKAGE__->register_type('jsonrpc');
19              
20 21     21 1 67 sub url { return shift->{url} }
21              
22             my $request_number = 0;
23              
24             sub call_rpc {
25 21     21 1 55 my ($self, $c, $req_storage) = @_;
26 21         143 state $client = MojoX::JSON::RPC::Client->new;
27              
28 21   33     132 my $url = $req_storage->{url} // $self->url;
29 21 50       51 die 'No url found' unless $url;
30              
31 21         50 $url .= $req_storage->{method};
32              
33 21         46 my $method = $req_storage->{method};
34 21   66     114 my $msg_type = $req_storage->{msg_type} ||= $req_storage->{method};
35              
36 21   50     115 $req_storage->{call_params} ||= {};
37              
38 21         110 my $rpc_response_cb = $self->get_rpc_response_cb($c, $req_storage);
39              
40 21   50     68 my $before_get_rpc_response_hook = delete($req_storage->{before_get_rpc_response}) || [];
41 21   50     84 my $after_got_rpc_response_hook = delete($req_storage->{after_got_rpc_response}) || [];
42 21   50     59 my $before_call_hook = delete($req_storage->{before_call}) || [];
43              
44 21         179 my $callobj = {
45             # enough for short-term uniqueness
46             id => join('_', $$, $request_number++, time, (0 + [])),
47             method => $method,
48             params => $self->make_call_params($c, $req_storage),
49             };
50              
51 21         79 $_->($c, $req_storage) for @$before_call_hook;
52              
53             $client->call(
54             $url, $callobj,
55             $client->$curry::weak(
56             sub {
57 21     21   129222 my $client = shift;
58 21         36 my $res = pop;
59              
60 21         46 $_->($c, $req_storage) for @$before_get_rpc_response_hook;
61              
62             # unconditionally stop any further processing if client is already disconnected
63 21 50       71 return unless $c->tx;
64              
65 21         100 my $api_response;
66 21 50       71 if (!$res) {
67 0         0 my $tx = $client->tx;
68 0         0 my $details = 'URL: ' . $tx->req->url;
69 0 0       0 if (my $err = $tx->error) {
70 0   0     0 $details .= ', code: ' . ($err->{code} // 'n/a') . ', response: ' . $err->{message};
71             }
72 0         0 warn "WrongResponse [$msg_type], details: $details";
73 0         0 $api_response = $c->wsp_error($msg_type, 'WrongResponse', 'Sorry, an error occurred while processing your request.');
74 0         0 $c->send({json => $api_response}, $req_storage);
75 0         0 return;
76             }
77              
78 21         52 $_->($c, $req_storage, $res) for @$after_got_rpc_response_hook;
79              
80 21 50       88 if ($res->is_error) {
81 0         0 warn $res->error_message;
82 0         0 $api_response = $c->wsp_error($msg_type, 'CallError', 'Sorry, an error occurred while processing your request.');
83 0         0 $c->send({json => $api_response}, $req_storage);
84 0         0 return;
85             }
86              
87 21         516 $api_response = $rpc_response_cb->($res->result);
88              
89 21 50       98 return unless $api_response;
90              
91 21         483 $c->send({json => $api_response}, $req_storage);
92              
93 21         112 return;
94 21         158 }));
95 21         12637 return;
96             }
97              
98             1;
99              
100             __END__