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   101 use strict;
  17         33  
  17         432  
4 17     17   87 use warnings;
  17         30  
  17         412  
5              
6 17     17   91 use parent qw(Mojo::WebSocketProxy::Backend);
  17         32  
  17         105  
7              
8 17     17   1019 use feature qw(state);
  17         39  
  17         1426  
9              
10 17     17   108 no indirect;
  17         30  
  17         122  
11              
12 17     17   9281 use curry;
  17         4360  
  17         530  
13              
14 17     17   5935 use MojoX::JSON::RPC::Client;
  17         32502  
  17         110  
15              
16             our $VERSION = '0.12'; ## VERSION
17              
18             __PACKAGE__->register_type('jsonrpc');
19              
20 21     21 1 90 sub url { return shift->{url} }
21              
22             my $request_number = 0;
23              
24             sub call_rpc {
25 21     21 1 62 my ($self, $c, $req_storage) = @_;
26 21         162 state $client = MojoX::JSON::RPC::Client->new;
27              
28 21   33     211 my $url = $req_storage->{url} // $self->url;
29 21 50       64 die 'No url found' unless $url;
30              
31 21         68 $url .= $req_storage->{method};
32              
33 21         63 my $method = $req_storage->{method};
34 21   66     135 my $msg_type = $req_storage->{msg_type} ||= $req_storage->{method};
35              
36 21   50     133 $req_storage->{call_params} ||= {};
37              
38 21         125 my $rpc_response_cb = $self->get_rpc_response_cb($c, $req_storage);
39              
40 21   50     76 my $before_get_rpc_response_hook = delete($req_storage->{before_get_rpc_response}) || [];
41 21   50     59 my $after_got_rpc_response_hook = delete($req_storage->{after_got_rpc_response}) || [];
42 21   50     81 my $before_call_hook = delete($req_storage->{before_call}) || [];
43              
44 21         189 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         63 $_->($c, $req_storage) for @$before_call_hook;
52              
53             $client->call(
54             $url, $callobj,
55             $client->$curry::weak(
56             sub {
57 21     21   113694 my $client = shift;
58 21         46 my $res = pop;
59              
60 21         73 $_->($c, $req_storage) for @$before_get_rpc_response_hook;
61              
62             # unconditionally stop any further processing if client is already disconnected
63 21 50       84 return unless $c->tx;
64              
65 21         123 my $api_response;
66 21 50       84 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         54 $_->($c, $req_storage, $res) for @$after_got_rpc_response_hook;
79              
80 21 50       100 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         663 $api_response = $rpc_response_cb->($res->result);
88              
89 21 50       85 return unless $api_response;
90              
91 21         631 $c->send({json => $api_response}, $req_storage);
92              
93 21         125 return;
94 21         217 }));
95 21         15181 return;
96             }
97              
98             1;
99              
100             __END__