File Coverage

blib/lib/Plack/Middleware/StackTrace/LinkedSource.pm
Criterion Covered Total %
statement 53 54 98.1
branch 12 18 66.6
condition 3 6 50.0
subroutine 10 10 100.0
pod 2 2 100.0
total 80 90 88.8


line stmt bran cond sub pod time code
1             package Plack::Middleware::StackTrace::LinkedSource;
2 2     2   46951 use strict;
  2         4  
  2         56  
3 2     2   8 use warnings;
  2         4  
  2         50  
4 2     2   377 use parent 'Plack::Middleware::StackTrace';
  2         223  
  2         7  
5 2     2   44560 use Plack::App::SourceViewer;
  2         25545  
  2         62  
6 2     2   9 use Plack::Util;
  2         2  
  2         36  
7 2         5 use Plack::Util::Accessor qw/
8             lib
9             viewer
10             view_root
11             force
12 2     2   6 /;
  2         2  
13              
14             our $VERSION = '0.14';
15              
16             sub prepare_app {
17 6     6 1 1998556 my ($self) = @_;
18              
19 6 50       15 if (!$self->lib) {
    0          
20 6         80 $self->lib([@INC]);
21             }
22             elsif (ref $self->lib ne 'ARRAY') {
23 0         0 $self->lib([$self->lib]);
24             }
25              
26 6 50       32 unless ($self->viewer) {
27 6         27 my $source_viewer = Plack::App::SourceViewer->new(root => $self->lib);
28 6         71 $source_viewer->prepare_app;
29 6         206 $self->viewer($source_viewer);
30             }
31              
32             $self->view_root
33 6 100       28 or $self->view_root('/source');
34              
35 6   66     39 $self->{_enabled} = ($self->force || !$ENV{PLACK_ENV} || $ENV{PLACK_ENV} eq 'development');
36             }
37              
38             sub call {
39 6     6 1 17217 my($self, $env) = @_;
40              
41 6 100       17 unless ($self->{_enabled}) {
42 1         5 return $self->app->($env);
43             }
44              
45 5         11 my $path = $self->view_root;
46              
47 5 100       49 if ($env->{PATH_INFO} =~ m!^$path!) {
48 2         3 my $path_info = $env->{PATH_INFO};
49 2         22 $path_info =~ s!^$path/!!;
50 2         5 local $env->{PATH_INFO} = $path_info;
51 2         4 return $self->viewer->call($env);
52             }
53              
54 3         16 my $res = $self->SUPER::call($env);
55              
56 3 50 33     21336 if ($res->[0] == 500 && Plack::Util::header_get($res->[1], 'content-type') =~ m!text/html!) {
57 3         40 my $body = $res->[2][0];
58 3         10 $self->_add_link(\$body);
59 3         13 $res->[2][0] = $body;
60             }
61              
62 3         9 return $res;
63             }
64              
65             sub _add_link {
66 3     3   3 my ($self, $body_ref) = @_;
67              
68 3         4 for my $lib_path (@{$self->lib}) {
  3         7  
69 36 100       172 next if $lib_path eq '.';
70 33 50       50 $lib_path =~ s!/!\\!g if $^O eq 'MSWin32';
71 33         21 ${$body_ref} =~ s!(\Q$lib_path\E[/\\]+([^\.]+\.[^\s]+)\s+line\s+(\d+))[^<]?!$self->_link_html($1, $2, $3)!eg;
  33         753  
  33         177  
72             }
73             }
74              
75             sub _link_html {
76 33     33   57 my ($self, $matched, $path, $line_count) = @_;
77              
78 33         23 $path =~ s!\\!/!g; # for win
79              
80 33         45 return qq|$matched|;
81             }
82              
83             1;
84              
85              
86             __END__