@@ -48,6 +48,27 @@ has title => (
4848 builder => ' _build_title' ,
4949);
5050
51+ has censor => (
52+ is => ' ro' ,
53+ isa => CodeRef,
54+ lazy => 1,
55+ default => sub {
56+ my $self = shift ;
57+
58+ my $custom = $self -> has_app && $self -> app-> setting(' error_censor' )
59+ or return \&_censor;
60+
61+ my $module = $custom =~ s / ::[^:]*?$// r ;
62+ my $function = $custom =~ s / ^.*::// r ;
63+
64+ require_module($module ) unless eval {
65+ $module -> can($function )
66+ };
67+
68+ return $module -> can($function );
69+ }
70+ );
71+
5172sub _build_title {
5273 my ($self ) = @_ ;
5374 my $title = ' Error ' . $self -> status;
@@ -367,11 +388,11 @@ sub backtrace {
367388}
368389
369390sub dumper {
370- my $ obj = shift ;
391+ my ( $self , $ obj) = @_ ;
371392
372393 # Take a copy of the data, so we can mask sensitive-looking stuff:
373394 my $data = clone($obj );
374- my $censored = _censor ( $data );
395+ my $censored = $self -> censor -> ( $data );
375396
376397 # use Data::Dumper;
377398 my $dd = Data::Dumper-> new( [ $data ] );
@@ -399,7 +420,7 @@ sub environment {
399420 my $env = $self -> has_app && $self -> app-> has_request && $self -> app-> request-> env;
400421
401422 # Get a sanitised dump of the settings, session and environment
402- $_ = $_ ? dumper($_ ) : ' <i>undefined</i>' for $settings , $session , $env ;
423+ $_ = $_ ? $self -> dumper($_ ) : ' <i>undefined</i>' for $settings , $session , $env ;
403424
404425 return <<"END_HTML" ;
405426<div class="title">Stack</div><pre class="content">$stack </pre>
@@ -523,6 +544,35 @@ This is only an attribute getter, you'll have to set it at C<new>.
523544
524545The message of the error page.
525546
547+ =attr censor
548+
549+ The function to use to censor error messages. By default it uses the
550+ C<_censor > function of this package, but it can be configured via the
551+ app setting 'error_censor'. If provided, C<error_censor > has to be
552+ the fully qualified name of the censor function to use. That function is
553+ expected to take in the data as a hashref, modify it in place and return
554+ the number of items 'censored'.
555+
556+ For example, using L<Data::Censor> .
557+
558+ # in config.yml
559+ error_censor: MyApp::Censor::censor
560+
561+ # in MyApp::Censor
562+ package MyApp::Censor;
563+
564+ use Data::Censor;
565+
566+ my $data_censor = Data::Censor->new(
567+ sensitive_fields => [ qw(card_number password hush) ],
568+ replacement => '(Sensitive data hidden)',
569+ );
570+
571+ sub censor { $data_censor->censor(@_) }
572+
573+ 1;
574+
575+
526576=method throw($response)
527577
528578Populates the content of the response with the error's information.
0 commit comments