File Coverage

blib/lib/Sentry/Transport/Http.pm
Criterion Covered Total %
statement 45 48 93.7
branch 7 10 70.0
condition 4 9 44.4
subroutine 10 10 100.0
pod 0 1 0.0
total 66 78 84.6


line stmt bran cond sub pod time code
1             use Mojo::Base -base, -signatures;
2 4     4   22  
  4         9  
  4         22  
3             use HTTP::Status qw(:constants);
4 4     4   790 use Mojo::JSON 'encode_json';
  4         13  
  4         1347  
5 4     4   1630 use Mojo::UserAgent;
  4         71752  
  4         247  
6 4     4   1954 use Mojo::Util 'dumper';
  4         596962  
  4         32  
7 4     4   165 use Readonly;
  4         8  
  4         166  
8 4     4   23 use Sentry::Envelope;
  4         6  
  4         146  
9 4     4   1663 use Sentry::Hub;
  4         17  
  4         25  
10 4     4   123 use Sentry::Logger 'logger';
  4         7  
  4         21  
11 4     4   110  
  4         6  
  4         2438  
12             Readonly my $SENTRY_API_VERSION => '7';
13              
14             has _http => sub {
15             Mojo::UserAgent->new(request_timeout => 5, connect_timeout => 1);
16             };
17             has _sentry_client => 'perl-sentry/1.0';
18             has _headers => sub ($self) {
19             my @header = (
20             "Sentry sentry_version=$SENTRY_API_VERSION",
21             "sentry_client=" . $self->_sentry_client,
22             'sentry_key=' . $self->dsn->user,
23             );
24              
25             my $pass = $self->dsn->pass;
26             push @header, "sentry_secret=$pass" if $pass;
27              
28             return {
29             'Content-Type' => 'application/json',
30             'X-Sentry-Auth' => join(', ', @header),
31             };
32             };
33             has _sentry_url => sub ($self) {
34             my $dsn = $self->dsn;
35             die 'DSN missing' unless $dsn;
36              
37             return
38             sprintf('%s://%s/api/%d', $dsn->protocol, $dsn->host_port,
39             $dsn->project_id);
40             };
41             has dsn => undef;
42              
43             return unless $self->dsn;
44 16     16 0 75 my $is_transaction = ($payload->{type} // '') eq 'transaction';
  16         103  
  16         19  
  16         26  
45 16 50       37 my $endpoint = $is_transaction ? 'envelope' : 'store';
46 16   100     90 my $tx;
47 16 100       43 my $url = $self->_sentry_url . "/$endpoint/";
48 16         85  
49 16         36 if ($is_transaction) {
50             my $envelope = Sentry::Envelope->new(
51 16 100       62 event_id => $payload->{event_id},
52             body => $payload,
53             );
54 8         54 $payload = $envelope->serialize;
55             $tx = $self->_http->post($url => $self->_headers, $payload);
56 8         88 } else {
57 8         10075 $tx = $self->_http->post($url => $self->_headers, json => $payload);
58             }
59 8         25  
60             logger->log(
61             sprintf(
62 16   50     713 qq{Sentry request done. Payload: \n<<<<<<<<<<<<<<\n%s\n<<<<<<<<<<<<<<\nCode: %s},
63             $tx->req->body, $tx->res->code // 'ERROR'
64             ),
65             __PACKAGE__
66             );
67              
68             if (!defined $tx->res->code || $tx->res->is_error) {
69             logger->warn('Error: ' . ($tx->res->error // {})->{message});
70 16 50 33     171 return;
71 0   0     0 }
72 0         0  
73             if ($tx->res->code == HTTP_BAD_REQUEST) {
74             logger->error($tx->res->body);
75 16 50       215 }
76 0         0  
77             return $tx->res->json;
78             }
79 16         109  
80             1;