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   24  
  4         6  
  4         24  
3             use HTTP::Status qw(:constants);
4 4     4   866 use Mojo::JSON 'encode_json';
  4         6  
  4         1514  
5 4     4   1661 use Mojo::UserAgent;
  4         74391  
  4         285  
6 4     4   2097 use Mojo::Util 'dumper';
  4         659423  
  4         56  
7 4     4   186 use Readonly;
  4         9  
  4         185  
8 4     4   25 use Sentry::Envelope;
  4         9  
  4         169  
9 4     4   1957 use Sentry::Hub;
  4         11  
  4         24  
10 4     4   124 use Sentry::Logger 'logger';
  4         5  
  4         22  
11 4     4   122  
  4         10  
  4         2562  
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 99 my $is_transaction = ($payload->{type} // '') eq 'transaction';
  16         21  
  16         21  
  16         28  
45 16 50       39 my $endpoint = $is_transaction ? 'envelope' : 'store';
46 16   100     216 my $tx;
47 16 100       40 my $url = $self->_sentry_url . "/$endpoint/";
48 16         20  
49 16         38 if ($is_transaction) {
50             my $envelope = Sentry::Envelope->new(
51 16 100       70 event_id => $payload->{event_id},
52             body => $payload,
53             );
54 8         61 $payload = $envelope->serialize;
55             $tx = $self->_http->post($url => $self->_headers, $payload);
56 8         85 } else {
57 8         9813 $tx = $self->_http->post($url => $self->_headers, json => $payload);
58             }
59 8         26  
60             logger->log(
61             sprintf(
62 16   50     809 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     191 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       252 }
76 0         0  
77             return $tx->res->json;
78             }
79 16         123  
80             1;