our
$VERSION
=
'1.40'
;
}
message_class
=>
'Dancer2::Plugin::LogReport::Message'
;
my
%_all_dsls
;
my
$_settings
;
sub
import
{
my
$class
=
shift
;
my
$level
= version->parse(
$Dancer2::Plugin::VERSION
) > 0.166001 ?
'+1'
:
'+2'
;
Log::Report->
import
(
$level
,
@_
,
syntax
=>
'LONG'
);
my
$caller
=
caller
;
$class
->SUPER::
import
( {
into
=>
$caller
} );
}
my
%session_messages
;
my
@default_reasons
=
qw/NOTICE WARNING MISTAKE ERROR FAULT ALERT FAILURE PANIC/
;
my
$hide_real_message
;
my
$messages_variable
=
$_settings
->{messages_key} ||
'messages'
;
on_plugin_import
{
my
$dsl
=
shift
;
$_all_dsls
{refaddr(
$dsl
->app)} =
$dsl
;
my
$settings
=
$_settings
= plugin_setting;
$dsl
->app->add_hook(
Dancer2::Core::Hook->new(
name
=>
'core.app.route_exception'
,
code
=>
sub
{
my
(
$app
,
$error
) =
@_
;
my
$is_fatal
=
$app
->request ? 1 : 0;
report {
is_fatal
=>
$is_fatal
},
'PANIC'
=>
$error
;
},
),
);
if
(
$settings
->{handle_http_errors})
{
$dsl
->app->add_hook(
Dancer2::Core::Hook->new(
name
=>
'after_error'
,
code
=>
sub
{
my
$error
=
shift
;
my
$msg
= __(
$error
->status .
": "
. Dancer2::Core::HTTP->status_message(
$error
->status));
_forward_home(
$msg
);
},
),
);
}
$dsl
->app->add_hook(
Dancer2::Core::Hook->new(
name
=>
'after_layout_render'
,
code
=>
sub
{
my
$session
=
$dsl
->app->session;
$session
->
write
(
$messages_variable
=> []);
},
),
);
my
$sm
=
$settings
->{session_messages} // \
@default_reasons
;
$session_messages
{
$_
} = 1
for
ref
$sm
eq
'ARRAY'
?
@$sm
:
$sm
;
if
(
my
$forward_template
=
$settings
->{forward_template})
{
$dsl
->app->add_route
(
method
=>
'get'
,
regexp
=>
qr!^/\Q$forward_template\E$!
,
,
code
=>
sub
{
shift
->app->template(
$forward_template
) }
);
$settings
->{forward_url} =
$forward_template
;
}
dispatcher
CALLBACK
=>
'error_handler'
,
callback
=> \
&_error_handler
,
mode
=>
'DEBUG'
unless
dispatcher
find
=>
'error_handler'
;
Log::Report::Dispatcher->addSkipStack(
sub
{
$_
[0][0] =~
m/ ^ Dancer2\:\:(?:Plugin|Logger)
| ^ Dancer2\:\:Core\:\:Role\:\:DSL
| ^ Dancer2\:\:Core\:\:App
/x
});
};
sub
process($$)
{
my
(
$dsl
,
$coderef
) =
@_
;
ref
$coderef
eq
'CODE'
or report
PANIC
=>
"plugin process() requires a CODE"
;
try
{
$coderef
->() }
hide
=>
'ALL'
,
on_die
=>
'PANIC'
;
my
$e
= $@;
$e
->reportAll(
is_fatal
=> 0);
$e
->success || 0;
}
register
process
=> \
&process
;
my
@user_fatal_handlers
;
plugin_keywords
fatal_handler
=>
sub
{
my
(
$plugin
,
$sub
) =
@_
;
push
@user_fatal_handlers
,
$sub
;
};
sub
_get_dsl()
{
my
(
@ret
,
$ref
,
$i
);
do
{
@ret
=
caller
++
$i
}
until
!
@ret
|| ( blessed
$DB::args
[0]
&& blessed
$DB::args
[0] eq
'Dancer2::Core::App'
&& (
$ref
= refaddr
$DB::args
[0] )
)
|| ( blessed
$DB::args
[1]
&& blessed
$DB::args
[1] eq
'Dancer2::Core::App'
&& (
$ref
= refaddr
$DB::args
[1] )
);
$ref
?
$_all_dsls
{
$ref
} :
undef
;
}
sub
_message_add($)
{
my
$msg
=
shift
;
return
if
!
$session_messages
{
$msg
->reason}
||
$msg
->inClass(
'no_session'
);
my
$dsl
= _get_dsl();
if
(!
$dsl
)
{ report {
to
=>
'default'
},
NOTICE
=>
"Unable to write message $msg to the session. "
.
"Have you loaded Dancer2::Plugin::LogReport to all your separate Dancer apps?"
;
return
;
}
my
$app
=
$dsl
->app;
return
unless
$app
->request;
my
$fatal_error_message
= !
$dsl
->app->config->{show_errors}
&& (
$_settings
->{fatal_error_message} //
"An unexpected error has occurred"
);
$hide_real_message
->{
$_
} =
$fatal_error_message
for
qw/FAULT ALERT FAILURE PANIC/
;
my
$r
=
$msg
->reason;
if
(
my
$newm
=
$hide_real_message
->{
$r
})
{
$msg
= __
$newm
;
$msg
->reason(
$r
);
}
my
$session
=
$app
->session;
my
$msgs
=
$session
->
read
(
$messages_variable
);
push
@$msgs
,
$msg
;
$session
->
write
(
$messages_variable
=>
$msgs
);
return
(
$dsl
||
undef
,
$msg
);
}
sub
_forward_home($)
{
my
(
$dsl
,
$msg
) = _message_add(
shift
);
$dsl
||= _get_dsl();
my
$page
=
$_settings
->{forward_url} ||
'/'
;
my
$req
=
$dsl
->app->request or
return
;
return
$dsl
->send_as(
plain
=>
"$msg"
)
if
$req
->uri eq
$page
&&
$req
->is_get;
$dsl
->redirect(
$page
);
}
sub
_error_handler($$$$)
{
my
(
$disp
,
$options
,
$reason
,
$message
) =
@_
;
my
$default_handler
=
sub
{
return
_message_add(
$message
)
if
exists
$options
->{is_fatal} && !
$options
->{is_fatal};
_forward_home(
$message
);
};
my
$user_fatal_handler
=
sub
{
my
$return
;
foreach
my
$ufh
(
@user_fatal_handlers
)
{
last
if
$return
=
$ufh
->(_get_dsl,
$message
,
$reason
);
}
$default_handler
->(
$message
)
if
!
$return
;
};
my
$fatal_handler
=
@user_fatal_handlers
?
$user_fatal_handler
:
$default_handler
;
$message
->reason(
$reason
);
my
%handler
=
(
default
=>
sub
{ _message_add
$message
}
,
ERROR
=>
$fatal_handler
,
FAULT
=>
$fatal_handler
,
ALERT
=>
$fatal_handler
,
FAILURE
=>
$fatal_handler
,
PANIC
=>
$fatal_handler
);
my
$call
=
$handler
{
$reason
} ||
$handler
{
default
};
$call
->();
}
sub
_report($@) {
my
(
$reason
,
$dsl
) = (
shift
,
shift
);
my
$msg
= (blessed(
$_
[0]) &&
$_
[0]->isa(
'Log::Report::Message'
))
?
$_
[0] : Dancer2::Core::Role::Logger::_serialize(
@_
);
if
(
$reason
eq
'SUCCESS'
)
{
$msg
= __
$msg
unless
blessed
$msg
;
$msg
=
$msg
->clone(
_class
=>
'success'
);
$reason
=
'NOTICE'
;
}
report
uc
(
$reason
) =>
$msg
;
}
register
trace
=>
sub
{ _report(
TRACE
=>
@_
) };
register
assert
=>
sub
{ _report(
ASSERT
=>
@_
) };
register
notice
=>
sub
{ _report(
NOTICE
=>
@_
) };
register
mistake
=>
sub
{ _report(
MISTAKE
=>
@_
) };
register
panic
=>
sub
{ _report(
PANIC
=>
@_
) };
register
alert
=>
sub
{ _report(
ALERT
=>
@_
) };
register
fault
=>
sub
{ _report(
FAULT
=>
@_
) };
register
failure
=>
sub
{ _report(
FAILURE
=>
@_
) };
register
success
=>
sub
{ _report(
SUCCESS
=>
@_
) };
register_plugin
for_versions
=> [
'2'
];
1;